Daniela Koller: Indexer für mein Forum basteln

Beitrag lesen

Hi Andreas

Nein, dann such ich immernoch nur in Keywd_Item. Part_Keywd kommt erst ins Spiel, wenn man vor dem zu suchenden Teilwort ein * angibt.

na, _das_ muß einem ja auch gesagt werden ;-)

Es kommt noch eine Anleitungsseite oder ein Kasten. Der ist nur noch nicht fertig.

Nicht ganz. Eigentlich ist das ganze eine uncorrelated Subquery, es muss also nur einmal die Liste aller möglichen Wörter ermittelt werden und nicht pro Item. So artet das bei Postgres in einen Nested Loop aus.

fürchte, das ist mir zu hoch, aber ich brauche es ja auch nicht so komplex wie Du, nur eine Frage ist noch übrig:

Es ist eigentlich ganz einfach: Die verschiedenen möglichen Wörter die für ein Teilwort möglich sind, unterscheiden sich bei den einzelnen Ergebnissen nicht. Beim Dokument 1 sind sie identisch mit denen von Dokument n. Sie sind unabhängig vom Rest der Query. Das nennt man eine "uncorrelated" Subquery. Nur hab ich es nicht hingekriegt das Postgres begreiflich zu machen, dass er bitte nicht für jeden Möglichkeit des äusseren Joins (oder in meinem Fall auch Query da ich es sowohl als Subquery als auch über Joins probiert hatte), nochmal die Tabelle Part_Keywd anschauen soll, sondern dass ein einziges Mal für die ganze Query reicht.

Wie muß denn eine 'gute' Reihenfolge sein? Und wie bestimme ich die? Mein Beispiel:

SELECT Itemid
From Keywd_Item, Part_Keywd
WHERE Keywd_Item.Keywd = Part_Keywd.Keywd
AND Part_Keywd.PartKeywd = 'ndreas'

braucht ja nicht wirklich eine Join-Angabe, um überhaupt die richtigen Ergebnisse zu liefern. Das ist doch automatisch ein inner-Join gell? Ich bin so in den Tiefen eines DB-Systems nicht bewandert, daß ich jetzt wüßte, was besser, schneller, wasauchimmer ausgeführt wird.

Nein, das ganze spielt erst bei mehreren verschiedenen Schlüsselwörtern einer Rolle. Bei grossen Zwischenergebnissen sagen wir einmal 10000 Treffer für ein einzelnes Wort wird ein Merge mit einem anderen, ebenfalls sehr grossen, Zwischenergebnis ziemlich teuer. Ich sortiere die Joins deswegen in einer Reihenfolge die, nach Möglichkeit, erstmal eine kleine Menge mit einer grossen Menge zusammenmergt und so in jedem Fall sämtliche Zwischenresultate kleiner oder maximal gleich Gross wie die kleinste Menge sind.

Ein Beispiel:

Eine Suche nach Perl, Javascript und noch einem seltenen Wort. Perl und Javascript sind hier sehr häufige Wörter da sie gleichzeitig Kategorien darstellen. Wenn jetzt zuerst die beiden Ergebnismengen von Perl und Javascript zusammengefügt werden, müssen zwei sehr grosse Mengen zusammengeführt werden. Wenn jetzt aber erst eine der Mengen mit den sagen wir mal 100 Treffern des seltenen Wortes zusammengefügt werden, geht das viel schneller.

Das kannst du recht gut an den Explains der Query sehen. Ich weis nicht ob MySQl die Möglichkeit auch bietet, aber mit Postgres kann man sich die effektiv benötigte Zeit von jedem Zwischenschritt mit explain analyze ansehen. Wenn da Joins egal welcher Art sehr lange dauern, kann es daran liegen. Durch eine bessere Sortierung der Reihenfolge der Wörter und damit der Joins etwas verbessert werden. Teilweise war es bei mir von 30s auf 0.5s, das waren allerdings die Extreme.

Die Reihenfolge vorgeben kann man allerdings, zumindest bei Postgres, nur mit expliziter geklammerter Joins:

FROM x
     INNER JOIN (y INNER JOIN z on(y.asdf = z.asdf)) on(x.asdf = y.asdf)

äh, ja. Das konnte ich halt nicht glauben, deshalb habe ich mal nachgefragt. Also in _einer_ Datei für die Sektion Forum z.B. stehen _alle_ Volltexte des Archivs oder eines Ausschnitts davon?

Fast, das Forum ist unterteilt in verschiedene Sektionen. Die Daten sind so aufgeteilt, wie du sie auswählen kannst in der Maske. Es steht nicht nur ein Ausschnitt drin, sondern alles (das was auch der User sieht, also keine Tags und sowas).

Ich vermute, da haben wir das gleiche gemeint. Also erst Suche nach _allen_ Wörtern der Eingabe und die gefunden Postings dann auslesen und die tatsächliche Phrase vergleichen ja?

Jap.

Gruss Daniela