daß die Archivsuche nicht prinzipiell an den technischen Möglichkeiten scheitert, bekommt man ja jederzeit deutlich von Altavista & Co. vorgeführt - dort wird eine um Größenordnungen größere Datenmenge in einem Bruchteil der Zeit durchsucht - und das von einer um Größenordnungen größeren Menge an Leuten - so daß es also nicht einzig an einem schnelleren Rechner oder so liegen kann.
Sondern an cleveren Datenstrukturen und Algorithmen, in der Tat.
Deine Idee mit der Auflösung der Phrasensuche in Teiloperationen könnte genau der Weg zum Sieg sein - hier haben mir die Profis natürlich Jahre an Erfahrung und Performance-Tests voraus.
Diese Tabelle könnte man dann auf 10000 Dateien verteilen, was zwar nach viel klingt, aber angesichts der Anzahl von mittlerweile >50000 Forumsbeiträgen auch nicht mehr ins Gewicht fällt <g>.
Und diese Dateien dann in mehrstufigen Unterverzeichnissen ablegen, damit nicht die lineare Suche des Betriebssystems nach dem Dateinamen einiges wieder kaputt macht!
(Also maximal diejenige Anzahl von Dateien in einem Verzeichnis ablegen, welche vom Betriebssystem in einem directory buffer gecached wird - hier wird es wieder implementierungsabhängig, aber das Prinzip ist klar. Ich denke, bei 10000 Dateien werden 100 Verzeichnisse mit je 100 Dateien reichen, aber wir können auch gerne vier Ebenen mit je 10 Dateien ausprobieren ...)
Im Klartext: Der Ergebnistyp der Hash-Funktion sollte ein n-Tupel überschaubar kleiner Werte sein. (Das können ja auch Buchstaben sein, falls Datei- bzw. Verzeichnisnamen aus Zahlen nicht erwünscht sein sollten.)
Eine Suche würde dann für jedes Suchwort wie folgt ablaufen:
1.) Hashfunktion des Suchwortes berechnen (geht schnell).
2.) Das Ergebnis wäre z.B. eine Zahl zwischen 0 und 9999.
Die entsprechende Indexdatei wird geöffnet.
3.) Alle Einträge (die in der oben erwähnten Form vorliegen) in dieser Datei
durchsuchen, ob sie mit dem Suchwort übereinstimmen und gegebenenfalls
die entsprechenden Archivlinks ausgeben.
Das ist eine relativ kleine Änderung im Suchskript - kein echtes Problem.
Über die Verwendung mehrerer Indexe hatte ich ja bereits nachgedacht - den Namen zu berechnen, kann nicht das Problem sein. Ich denke, das ist eine zusätzliche Funktion mit ca. 30 Zeilen.
Bei Und/Oder-Verknüpfungen müßte man diese Schritte mehrmals mit den einzelnen Wörtern durchführen
... und die Zwischenergebnisse im Speicher halten, um sie später zu JOINen - genau hier beginnt die Sache, tricky zu werden bzw. Ressourcen zu kosten.
Deshalb habe ich bewußt kein ODER und keine rekursiven Ausdrücke implementiert, sondern nur die Trivial-Operatoren AND und NOT.
und bei Suchbegriffen aus mehreren Wörtern hintereinander müßte man vielleicht erstmal nach den einzelnen Wörtern suchen und dann in der "Lösungsmenge" nochmals kontrollieren, ob die Worte auch hintereinander stehen - sollte immer noch deutlich schneller gehen als wie bisher.
Phrasensuche als mehrfache Schlagwortsuche mit Nachbearbeitung emulieren, das ist es! Das sollte das Problem der Phrasensuche (die wahrscheinlich ohnehin nicht so wahnsinnig häufig anfällt und gerne etwas langsamer sein darf) in den Griff bekommen.
Angenommen, ein Durchschnittsbeitrag hat ca. 500 Wörter (hat dieser hier in etwa), dann wären wir bis jetzt bei einer Gesamtzahl von ca. 30 Millionen Wörtern für alle Beiträge.
Es sind derzeit 40+ MB Index (der fast nur den Volltext der Postings enthält) aus 50000+ Beiträgen, die also im Mittel keine 800 Bytes lang sind - davon vielleicht 50-100 Bytes Verfasser, Titel, Datum und relativer URL.
Also eher zwischen 100 und 200 Wörtern. Aber in 2-3 Jahren werden wir die von Dir beschriebenen Dimensionen erreicht haben. ;-)
Das heißt, in jeder Einzeldatei der Hashtabelle stehen durchschnittlich gut 3000 Einträge, was sich im Ggs. zu >25 MB relativ schnell durchsuchen lassen sollte.
Yep. Die Frage ist allerdings, ob es wirklich diese Einträge sein sollten, die durchsucht werden! (Siehe unten.)
Wenn man gleiche Wörter in verschiedenen Beiträgen noch zusammenfaßt, so daß man Einträge der Form
{wort, Liste von Links auf Archivbeiträgen und Anker}
erhält, wird die zu durchsuchende Datenmenge weiter reduziert.
Genau hier wird es wieder teuer.
Bedenke, daß dann der Indexer nicht mehr so leicht inkrementell arbeiten kann!
Und wenn der Schwanzabschneider jedesmal den gesamten Index Datei für Datei einlesen, um eine Handvoll Einträge erweitern und dann wieder abspeichern muß, dann wird Stefan Dir was husten ... ;-)
Deshalb würde ich an dieser Stelle das derzeitige Konzept mit Anhängen neuer Einträge an das Ende von Indexdateien nicht ohne Not opfern.
Insbesondere wächst die Datenmenge linear und nicht exponentiell.
Yep. Die Aufgliederung einer komplexen Suche in mehrere einfache Suchen ist es, durch die der Platzbedarf wieder zurück in Zeitbedarf getauscht wird.
Allerdings wird der Index auf diese Weise dann
trotzdem insgesamt *sehr* viel größer als bisher. Denn das Format (und damit das Volumen) eines Indexeintrages ändert sich ja zunächst einmal nicht, und ein Posting mit 200 Worten kann (und sollte, wenn die Hash-Funktion etwas taugt!) sehr wohl simultan in 200 verschiedenen Indexdateien eingetragen werden!
Der Index wird dann also um Faktor 200 größer, und der Indexer wird wesentlich langsamer - das ist der Preis für die schnellere Suche. (Haben wir 8 GB auf der Platte verfügbar? Tendenz steigend! Die Profis haben natürlich fette Server ...)
Es gäbe allerdings eine Alternative.
Der Index enthält bisher pro Zeile den Volltext des Postings.
An dieser Stelle könnte man wiederum eine Abstraktionsebene einziehen und in den Index nur einen Verweis auf die Posting-Datei (oder auf eine für Suchzwecke optimierte Version derselben, also das, was bisher im Index-Feld "body" steht) eintragen. Gewinn: Faktor 100-200 an Speicherplatz, weil das Posting nun wieder nur ein oder zweimal auf der Platte steht. Preis: Eine große Anzahl weiterer Dateizugriffe, weil jeder einzelne body erst aus einer Datei eingelesen werden muß. (So optimiert man halt ständig zwischen Zeit und Platz hin und her ...)
Und diese Dateien sollten dann ggf. wieder eine pro Posting sein, also 50000+ Dateien, mit denselben Infrastrukturmaßnahmen wie für den hashed index ... hm ... so etwa sieht es eben aus, wenn man eine hierarchische Datenbankstruktur in Perl realisieren will.
Im Detail habe ich sowas noch nicht gesehen, vielleicht gibt's entsprechende Skripte ja auch schon irgendwo fertig zum Download
Kennt sich jemand gut genug mit CPAN-Modulen aus, um das zu beantworten? (Cheatah?)
aber als Idee wollte ich das einfach mal anregen...
Ich denke, das meiste von dem, was Du beschrieben hast, ist nicht wirklich schwer zu realisieren. (Insbesondere das parallele Generieren vieler Dateien durch den Total-Indexer habe ich im Dezember selbst in Perl programmieren müssen, und durch ein hilfreiches Forum-Posting ging das sehr elegant.)
Es muß halt auch der Indexer zu jedem Posting den Hash-Wert berechnen und begreifen, an welche der vielen Dateien er die aktuelle Zeile anhängen muß.
Bei dem bereits modularisierten Suchskript sind es nur zwei oder drei von 13 Funktionen, die von einer derartigen Architekturänderung betroffen sind. Davor habe ich überhaupt keine Angst.
Der Schwanzabschneider dagegen müßte wahrscheinlich in einen Inhaltsparser (der tags eliminiert, Steuerzeichen umcodiert etc.) und einen Indexer aufgeteilt und danach zur Hälfte neu geschrieben werden - wer hat Lust dazu?