Andres Freund: (PERL)Suchmaschienen-Stuktur

Beitrag lesen

Hi Michael

Ich verstehe, daß Du die jeweilige Datenmenge klein halten willst; aber wenn Du über die Worte einen Indexbaum legst, dann macht die Datenbank das von ganz alleine. Ich vermute, Du wirst einen sehr kleinen Performance-Gewinn erzielen, aber die Wartung Deiner Datenstrukturen nicht gerade vereinfachen.

Ich hab das ganze mit einem zufallsgenerierten Inhalt mal getestet, waren so 10-15 Prozent Geschwindigkeitszuwachs, je nach der durchschnittlichen Wortlänge. Allerdings ist bei zufallgeneriertem Content die Verteilung der Anfangsbuchstaben natürlich vergleichsmäßig gleichmäßig. Ausserdem waren das schon 1GB Daten, weil ich mich igrgendwo verschrieben/verrechnet hatte. Ich weiß es bis jetzt noch nicht genau was ich falsch gemacht habe ;-).
Ein zusätzlicher Grund für mich war, dass das ganze eventuell bei einem hoster läuft der zwar mehrere DB's pro Paket gibt, aber alle mit einer maximalgröße von 100MB. Dafür wäre eine derartige Datenstruktur prinziell ja gut geignet.

Du meinst "Substring" statt "Präfix", ja? (Präfix-Suche auf Postfixe ist Substring auf Worte.)

(geschmacks)(sache)
Mit Präfix meinte ich z.B. den ersten Teil der jetzt in der Klammer steht. Ob das jetzt eigentlich substring heißt, weiß ich ehrlichgesagt nicht.

Hm. Warum nicht das Wort mit Umlaut zweimal indexen? So oft kommt das ja nicht vor.

Weil ich 1. so keine Probleme mit dem Zeichesatz in der Tabelle habe, zweitens weil ich dadurch das Problem vermeide, dass jemand nach fröhlich sucht, aber in dem Text stand froelich, und er dadurch nichts findet.

Ich glaube nicht an das Prinzip mit den vielen Tabellen - es sei denn, bei Verteilung auf viele Maschinen. Aber auch dann würde man eine besser streuende Hash-Funktion nehmen und nicht die extrem ungleich verteilten Anfangs-Buchstabenpaare.

Wegen der Verteilunng, siehe oben.

Eine bessere Verteilung könnte man allerdings recht gut einbauen, z.B. indem man einige Zeit die Verteilung der Anfangsbuchstäben der Einträge verfolgt und dann, diese später wieder neu sortiert/verteilt. Das hat allerdings den Nachteil dass der Server dazu einge Zeit in Anspruch genommen wird. Besonders nachteilig müsste sich das dann auswirken, wenn man z.B. bei Puretec ist, mit einer maximalen Laufzeit von 6s. Ein Problem ist auch das generieren der Indices bei den großen Tabellen. Daher hätte, besonders bei mysql, eine auf viele Tabellen verteilte Struktur performance-Vorteile beim erstellen erneuern der Indices, da rel. Häufig Daten verschwinden und hinzukommen werden.

d: Wie soll ich suchen wenn mehr als ein Suchbegriff eingegeben wird? Soll ich suchen welche das gleich Ziel haben, und diese nach dem zweiten Suchbegriff durchsuchen? Oder das Ziel des ersten Suchbegriffes über Perl öffnen und mittels Regexen durchsuchen?
Genau darüber haben Andreas und ich lange diskutiert. ;-)
Das Problem ist: Wenn beide Terme viele Ergebnisse liefern, dann wird das JOIN zwischen beiden mörderisch und macht die schöne Indexstruktur wertlos.

Ich dachte mir, dass ich das ganze aufteile, das erste Wort, oder eben das längere Wort zuerst alleine in der Db suche, mit einem Limit von z.B. tausend. Ich suche nur die Ziele heraus, die z.B. in einer einfachen Text-Datei liegt. Diese durchsuche ich dann mittel Regexes nach dem Vorkommen des zweiten Wortes, wieder nur bis ich hundert habe, die dann in irgendeiner Form ausgebe.
Die andere Idee war die, dass ich, wenn ein Suchbegriff z.B. "Hallo" ist, alle Ziele in einem einfachen Array speichere, dann ohne irgendwelche besondere Maßnahmen das zweite Wort genauso durch die Db laufen lasse (Mit einem Statemant der Art: SELECT ziel FROM xyz WHERE wort=Hallo). Danach vergleiche ich die Ergebnisse der ersten Abfrage, mit denen der zweiten. Wenn bei einem Array Element eine Übereinstimmung mit einem Ergebniss der zweiten Abfrage vorliegt, öffne ich die Datei in der das ganze steht und gebe den anfang des Inhaltes aus. Das hat leider Ja den Nachteil, dass ich sehr viele Arraylemte miteinander vergleichen müstes. Bei einem dritten Wort wären in dem Array aber nur noch die "Ziele", die schon Übereingestimmt habe, was vermutlich nicht sonderlich viele sind. Dadurch wird das Ergebniss mit zusätlichen Suchbegriffen nicht alzu sehr langsamer.
Das mit dem Join würde nat. wieder sehr viele Resourcen auf dem Db Rechner benötigen.

Mein Vorschlag dazu war es, eine Meßfunktion für die Projektivität der Terme zu haben (die selbst dann möglichst wenig kosten darf) und damit Performance-Katastrophen wenigstens erkennen kann.

Etwas derartiges ist leider, befürchte ich, für einen, der in meinem Stadium des lernens ist, ein wenig zu anspruchsvoll. Ich werde mir aber die alten Threads von euch noch mal anschauen, vielleicht werde ich ja inspiriert.

So, hier nocheinmal die allgemeine Tabellenstruktur so wie ich sie mir momentan vorstelle:

-----------------------------------------------------------
|  Wort   |  Ziel  | Präfix/Substring | Kategorie | Autor |
-----------------------------------------------------------
|Belastung| 1d4df2 |0                 | Lacke     | Andres|
-----------------------------------------------------------
|stung    | 13s44d |1                 | Lacke     | Andres|
-----------------------------------------------------------
|FCKW     | 1s2442 |0                 | Lacke     |Michael|
-----------------------------------------------------------

Was dadurch ersichtlich wird, was ich eventuell *g* früher hätte erwähnen hätte sollen, ist, dass ich den "ganzen Content" eigentlich nicht zusammenhängend in der DB speichern wollte, da mir das IMHO kaum nutzen bringt, wenn ich teilweise keinen fulltext index benutzen kann, will.

Dem jetzt langsam, aber sehr sicher der Kopf raucht, und der langsam ins Bett gehen sollte weil er morgen früh wieder in der Schule (noch 2 1/2 Jahr ;-( )sein muss. Der auch _viel_ lieber anfangen würde etwas derartiges zu studieren. Ja, ich weiß lieber jetzt richtig lernen als später nachlernen *g*.

mfg und vielen, vielen Dank:
Andres (Michael) Freund  *g* wirklich, ich heiß auch Michael