Hi Andreas,
Verstehe ich nicht. Ich benutze doch keine Indizes?!
Solltest Du aber.
Das sieht dann wohl so aus:
SELECT...WHERE feld1 LIKE '%$suchwort%' OR feld2 LIKE '%$suchwort%';
Richtig?
Ja.
Klar das das langsamer ist als wenn ich nur suche ob Feld = $suchwort,
oder was meintest Du?
Stell Dir vor, Du hast eine Million Datensätze. Jede Deiner beiden Suchanfragen muß dann also eine Million Vergleiche durchführen. Das ist nicht wirklich beliebig schnell.
Und jetzt denke Dir zum Vergleich einen Index hinzu, also einen binären Baum, welcher sämtliche Werte des zu vergleichenden Feldes enthält. Wie findest Du (genauer gesagt: die SQL engine) darin einen Wert? Durch fortgesetzte Halbierung der Datenmenge, d. h. durch Absteigen in diesem Baum. Wieviele Schritte sind dafür notwendig? So viele, wie der Baum 'hoch' ist - im idealen Fall also Logarithmus zur Basis 2 von einer Million, also etwa 20. Und daß 20 Vergleiche schneller sind als eine Million, darüber sind wir uns doch einig, ja?
Genau diese Baum-Halbierungs-Methode funkioniert aber nur dann, wenn Du Suchbegriff auf den Anfang der gespeicherten Worte anwenden kannst - deshalb darf die wildcard nicht am Anfang vorliegen, sonst geht wiederum nur der lineare Vergleich aller Datensätze.
Aber wenn das Suchwort irgendwo im Text vorkommen kann, muß ich das
wohl so machen, oder geht das auch anders?
Das kommt darauf an, wie Du Deinen Text gespeichert hast.
Wenn Dein gesamter Text ein Feld der Tabelle ist _und_ Du nichts anderes verwenden willst als Dein obiges Statement, dann droht Dir die "eine-Million-Vergleiche-Strafe".
Zu diesem Modell gibt es zwei naheliegende Alternativen:
1. Du speicherst in einer weiteren Tabelle sämtliche Worte Deines Textes, je ein Wort pro Zeile, und als zweite Spalte den Primärschlüssel aus der ersten Tabelle. (Den Worte-Zerleger mußt Du Dir natürlich selbst schreiben.)
Nun kannst Du in der zweiten Tabelle Worte suchen und zu jedem Treffer aus der ersten Tabelle das zugehörige Dokument finden.
Und solange Du Dich auf Worte beschränkst (im Gegensatz zu Phrasen, also beliebigen Text-Teilen inklusive Wort-Trennern), kommst Du mit diesem Modell prima aus - und für eine exakte Übereinstimmung zwischen Deinem Suchbegriff und einem einzelnen Wort kannst Du wiederum den Index über die Worte-Spalte der zweiten Tabelle nutzen (das macht die Datenbank von alleine, Du mußt den Indexe einfach nur anlegen, gefüllt wird er beim Einfügen Deiner Worte in die Tabelle).
2. Du überläßt es mySQL, sich mit dem Problem zu befassen.
mySQL hat seit Version 3.23.23 eine eingebaute Volltextsuche! Lies Dir mal das Kapitel über FULLTEXT-Indexe durch ...
Viele Grüße
Michael
(der am Freitag versuchsweise die Konstante für die Wort-Mindestlänge für FULLTEXT im mySQL-Source von 4 auf 3 Zeichen geändert hat, was zu einer Zunahme von gerade mal 15% der Indexbaumgröße geführt hat ... Daniela, willst Du das wirklich immer noch selbst implementieren für die neue Self-Suche? Eine Stopwortliste gibt es auch schon im Quelltext ... bisher eine englische, aber diese editieren und mySQL neu übersetzen ist kein Problem.)