Michael Schröpl: Suche online(funktionsfähig) / Perfromance-Verbesserungen?

Beitrag lesen

Hi Andreas,

Also eines habe ich gelernt:
Volltext ust genau das Falsche für so ein Forum ;-)

Keineswegs.

Implementiere ein AND für mehrere Terme, und Du wirst
sehr viel bessere Ergebnisse bekommen, auch ohne
ranking-Funktion. Eine wirklich gute Anfrage wird
ungefähr 3-5 Terme haben, und die wirst Du dann sehr
schnell mit sehr guten Ergebnissen beantworten können.

Bedenke, daß eine Suche nach nur einem Term so viele
Ergebnisse liefern muß, daß selbst die beste Ranking-
Funktion dadurch überfordert wird. Wie soll die Funk-
tion denn wissen, was eigentlich gesucht war?
Gehe lieber den Weg, die Suche so zu schreiben, daß
ein Anwender mit guten Suchbegriffen gute Ergebnisse
bekommt - Du kannst davon ausgehen, daß diejenigen
Leute, die sich überhaupt die Zeit nehmen, die Archiv-
suche zu bedienen, überdurchschnittlich viel Erfahrung
im Umgang mit Suchmaschninen haben.
Implementiere AND und NOT kompatibel zur bisherigen
Suche, und mach dann Deine Zeitmessungen nochmal.

Vor allem wenn man mehr sucht, dann wirds richtig
flott ;-)

Was lernst Du daraus? Es ist gar nicht die Suche, die
so lange dauert - es ist das Verarbeiten (vor allem
das Sortieren!) der Ergebnisse.
Halte die Ergebnismenge klein (beispielsweise mit einem
hart codierten LIMIT 200 in der Query), und Du wirst
dramatisch weniger CPU-Zeit verbrauchen.
Wer mehr als einige hundert Treffer erhält, dessen Fra-
ge war zu schlecht gestellt - Du hast jedes Recht, bei
einigen hundert Treffern abzubrechen. Und das lohnt sich!

Aber irgendwie versteh ich das ganze überhaupt
nicht. Jetzt denke ich ich hättte das mit einer
zusätzlichen Where Bedingung tierisch lahm gemacht,
dann macht es auf einmal gar nichts und ist so
schnell wie sonst, 10 Sekunden später braucht es
wieder 10 mal so lange... naja.

Das hängt von den Inhalten der WHERE-Klauseln ab.

Je selektiver Deine Suchbegriffe sind, desto schneller
ist die Treffermenge aus dem indexbaum extrahiert.
Eine Suche nach "HTML" dauert viel länger als eine
nach .htaccess!

Ich habe eine hart codierte Stopwortliste, die einige
zu häufige Suchbegriffe gar nicht mehr im FULLTEXT-
Index sucht, weil die Treffermengen zu groß werden.
Wenn Du HTML im Archiv suchst, bekommst Du eine fünf-
stellige Anzahl von Postings als Treffer - vielleicht
sogar eine sechsstellige. Wie soll das schnell werden?

Kann auch sein das es gerade da war wo ich einen
weiteren Index erstellt habe, da geht dann
eigentlich überhaupt nichts mehr und das dauert
tierisch lange bei 50MB Daten!

Du hast mein anderes Posting bezüglich paralleler
Tabellen gelesen?

Ich habe über die Namen einen "normalen" Index
erstellt, aber so viel merke ich davon auch nicht.

Kannst Du auch nicht, weil er nicht verwendet wird
(EXPLAIN!). Der macht nur das INSERT langsamer.
Substring-Funktionen arbeitet nicht mit Indexen.

Hatte einfach mal Lust, habe noch nie ne Such-
maschine progammiert, und wenn ich schon immer
mecker dann muß ich halt mal selbst schlechte
Erfahrungen machen ;-)

Mach weiter - als nächstes sind die guten Erfahrungen
dran. ;-)

Wer weiß denn, wie man die vernünftigen Postings
nach vorne bekommt? Einfach den Index rumdrehen
oder was?

Ignoriere das Ranking-Problem. Löse erst mal das Per-
formance-Problem und implementiere AND und NOT.
Dann wird die Sache so schnell und überschaubar, daß
Du eine Ranking-Funktion oben drauf stecken kannst.

Versuche nicht, eine Suche nach 'HTML' durch eine super-
sophisticated Ranking-Funktion zu tunen - konzentriere
Dich auf die sinnvollen Anfragen.

Mich würde aber tatsächlich mal interessieren, ob
es so wie es jetzt ist annehmnbar ist oder gräßlich
langsam!

Du hast zu große Treffermengen.
AND und LIMIT werden beide sehr viel bringen.

die volle Geschwindigkeit gibt es nur in Standard-
einstellung, sobald man die Suche weiter einschränkt
kostet das Geschwindigkeit - manchmal zumindest, ich
versteh es halt nicht.

Poste den exakten SQL-Code der generierten Anweisungen.

Für die Testphase: Implementiere einen zusätzlichen
CGI-Parameter "debug=1", welcher das generierte SQL-
Statement in die Ausgabe schreibt, sowie das Ergebnis
eines darauf angewendeten EXPLAIN, und am besten auch
die Anzahl der dabei erzielten Treffer nach jedem
Schritt. So lernst Du, wie sich die Ausführungspläne
der schnellen und der langsamen Statements voneinander
unterscheiden, und wann welche Deiner Indizes verwendet
werden und wann nicht.

Mal an einen DB-Spezialisten, welche Indizierung
würde hier denn jetzt wirklich Sinn machen?

Alles außer FULLTEXT ist momentan sinnlos. Im Augen-
blick sind Deine SQL-Stamements wichtiger, und das,
was die Datenbank daraus macht (EXPLAIN anwenden).

Meine sieht zur Zeit so aus:

KEY name (name),
  KEY name_2 (name)      *ups* ;-))) das war glaub ich der performancefressende Übeltäter!

Beim INSERT kostet das etwas, beim SELECT darf es
keinen Unterschied machen, weil es einfach ignoriert
wird.

Das ist ein Mist das dauert jetzt bestimmt 10
Minuten so nen blöden Index zu löschen!

Darüber habe ich mich bei mySQL auch schon geärgert.
Die Speicherung aller Indexe in _derselben_ Datei ist
grober Unfug, wenn Du mich fragst ...

"SELECT id,topic,title,name,time
   FROM selfarchiv
  WHERE MATCH (body,topic,title)
        AGAINST ('".mysql_escape_string($_GET['suchausdruck'])."')";
    AND name = '".mysql_escape_string($_GET['Verfasser'])."'";
    AND INSTR(name,'".mysql_escape_string($_GET['Verfasser'])."')>0";

Wie wird INSTR implementiert? Das kann eine Katastrophe
sein, weil es die Verwendung von Indexen abschalten
dürfte. Laß die Finger von Substring-Operationen -
vorerst jedenfalls. Wenn Du _das_ filtern willst, tue
es in PHP - da geht es schneller.

if($_GET['Listing']=="chronologisch"){
    $query_string .= " ORDER BY time DESC";

Auch das Sortieren ist teuer - allerdings sortiert
mySQL implizit nach seiner komischen Ranking-Funktion,
wenn man diese benutzt, glaube ich.
Prüfe mit EXPLAIN, ob sortiert wird - wenn ja, dann
unterdrücke es zunächst mal.

$query_string .= " LIMIT 0, $limit";

Setze eine hart codierte Obergrenze für das Limit.
Ich würde 200 vorschlagen - mehr Treffer liest eh
niemand.
Gib eine Meldung aus: "Diese Suche erzeugte zu viele
Treffer - bitte geben Sie exaktere Suchbegriffe an",
wenn Dein Limit erreicht wurde.

PS: Die Performance ist wirklch gut, habe oft Zeiten
erheblich unter 0,1 Sekunde(zugriffszeit auf die
DB), aber ich habe die ganze Zeit dran rumprobiert,
und nur einen der indices zu erstellen dauert weit
über eine halbe Stunde, und in der Zeit kann man die
DB vergessen!

In der endgültigen Produktionsversion wirst Du inkre-
mentell indexen, und das wird nicht mehr stören.

Viel Erfolg beim Probieren
     Michael