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

Beitrag lesen

Hi Andreas,

Der indes ixt jetzt erstellt, hat über 60 Minuten
gedauert. Wen ich jetzt suche, dauert es 1-2
Sekunden, bei bekannten Wörtern meist unter 0,1.

Was heißt "bekannte Wörter"?
(Meinst Du "gecachete Queries"?)

Was meinst DU, wenn ich nicht eine Datensatz pro
Thread verwende, sondern wie in der aktruelen Suche,
einen Datensatz pro Posting - wird das schneller
oder langsamer?

Etwas langsamer (weil mehr Treffer), aber viel bessere
Qualität der einzelnen Treffer (deshalb arbeitet die
bestehende Suche ja so).

Wenn ich bedenke das manche Suchworte nur ien
einigen wenigen Postings eines Threads vorlkommen
müßte das doch eigentlich besser gehen oder?

Du willst bestimmt keinen Thread als Treffer auslie-
fern, bei dem einer von zwei Suchtermen im einen und
der andere in einem anderen Posting verwendet wurde.
Deshalb wird die Trefferqualität besser, wenn Du die
einzelnen Postings separat indext.

Implementiere ein AND für mehrere Terme, und Du
wirst sehr viel bessere Ergebnisse bekommen ...
Aber da bräuchte ich dann mehrmals match against,

Ja, genau so mache ich das.

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 Funktion denn wissen, was eigentlich
gesucht war?
Klar, aber die Leute wissen oft leider nicht die
speziellen Wörter wonach sie sollten

Wenn Du entsprechend unklare Anfragen einfach ablehnst,
dann wirst Du die Anwender erziehen. Du kannst ja das
bisherige Eingabefeld mit den gesetzten Werten erneut
anbieten (wie die bisherige Suche) und den Anwender
auffordern, weitere Suchbegriffe einzugeben - diese
Ablehnung kann durchaus benutzerfreundlich ausfallen.

nach .htaccess!
Ja, das ist so wenn man nur den Fulltest verwendet,
aber wenn man echte Where spalte = $wert
dazuschreibt, wie ist das dann?

Das ist nicht relevant.
Entscheidend ist, daß der FULLTEXT-Zugriffe sehr
schnell eine Treffermenge berechnen kann - alles
Nachfolgende hängt von der Größe dieser Treffermenge
ab. Weitere Indexe wirken ab hier nicht mehr.

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.
Meine Suche müßte man von einigen Leuten probiert
werden, und ich müßte mal ne ganze Zeit lang die
Suchstrings loggen udn danach analysieren, dann
könnt eman so eine Liste machen.

Du verwendest bisher implizit den Wort-Indexer von
mySQL, welcher den FULLTEXT-Index aufbaut.
Ich habe mir so einen "Wort-Zerleger" selbst geschrie-
ben und meine gesamten "Postings" damit analysiert.
Danach habe ich die "Top 2%" aller Worte nach Häufig-
keit in eine Datei geschrieben und diese Liste manuell
(!) nach inhaltsleeren Füllwörtern durchsucht.
Alles, was ich für entbehrlich halte, ist auf die
Stopwortliste gewandert (C-Quelltext anpassen und
mySQL neu übersetzen), der Rest ist hard-coded in
meinem CGI-Skript drin und wird bei der Generierung
der MATCH-Terme ignoriert (falls ich mindestens einen
besser projezierenden Suchbegriff habe) - ich suche
damit nicht via FULLTEXT, brauche diese Wort aber
ggf. für Phrasen, darf sie also nicht aus dem Text
löschen.
Mein Super-GAU ist eine Suchanforderung, die aus-
schließlich aus Begriffen meiner 'schwarzen Liste'
besteht - dann muß ich halt in den sauren Apfel beißen.

Die kann dann mit einkompiliert werden, oder noch
besser - direkt aus allen Postings gelöscht werden.

Die Stopwortliste von MYISAM ist schneller, als Du
das in PHP lösen könntest. Denn Du müßtest ja erst
mal Deinen Text in Worte zerschlagen.

Eine Dolppelte Datenhaltung sollte hier besser sein,
der Performancxe zuliebe!

Wenn Du aus den gespeicherten Postings nicht selbst
wieder die Nachricht für die Anzeige erzeugen mußt
(bei mir ist das leider der Fall), dann kannst Du in
der Tat schon beim Importieren alles Entbehrliche
weglassen. Es muß sich aber auch lohnen.

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.
Was heißt nach jedem Schritt? Ich habe ein SQL-
Statement und das hat x Trefer, was soll ich da
schrittweise machen? Später vielleicht bei einem
eigenen Ranking!

Ja. Bei mir ist die Architektur wesentlich komplizier-
ter - meine SELECTs gehen erst mal in eine TEMPORARY
TABLE und werden dann in mehreren weiteren Schritten
zurechtgeschnitten (mir ist also die frühzeitige Be-
schränkung auf kleine Treffermengen noch wichtiger).
Mangels Subselect-Fähigkeit von mySQL kriege ich das
nicht besser hin.

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.
Zur Zeit habe ich nur einen, sollte ich mehr
verwenden? Vielleicht für verschiedene
Suchvariationen?

'Einen' was? Du verwendest nur einen Index - richtig.
Aber der Ausführungsplan wird von mySQL pro Statement
neu berechnet - der kann durchaus variieren, wenn
das RDBMS mehrere attraktive Alternativen findet (und
das wird bei Dir demnächst der Fall sein, siehe unten).

Weiß immer noch nicht, ob ich jetzt einen Index
pro Spalte anlegen soll oder einen über alle
Spalten.

Gleich kommt ein Fall, in dem Du _beides_ brauchst.

as doofe ist, ich kann das nicht "mal eben" testen,
das Anlegen würde mehrere Stunden dauern, die ich
die Tabelle dann nicht verwenen kann.

Teste mit mehreren parallelen Tabellen. Deren Name
in Deinem PHP-Skript ist ja schnell angepaßt.

Aber was bringt mir EPPLAIN denn jetz wirklich?
Es sagt ob es Fulltext verwendet, und sonst?

Das ist das Entscheidende.

Ist doch recht mager, oder?

Es zeigt Dir insbesondere die Anzahl der Zeilen, die
es angefaßt hat. Die unterscheiden sich bei verschie-
denen Suchbegriffen enorm.

Ich will z.B. bei der Eingabe von Andreas auch
spalten mit "Andreas Korthaus" finden.
ich will nicht alle Datensätze finden in denen
Andreas Irgendwo vorkommt, sindern mit Andreas
als Autor. Also braich ich eien zusätzliche
Bedingung. Und da eh nur ein Index verwendet wird,
kann ich auch keinen 2. Volltext-Index über diese
Spalte machen, denn den eigentlichen Fulltext
brauchte ich IMMER.

Richtig. Wenn Du eine Anfrage hast, die _nur_ nach
"Andreas" im Autor sucht, wirst Du einen FULLTEXT-
Index über das Feld "Autor" haben wollen. Hast Du
aber _auch_ andere Terme, die in mehreren Spalten
gesucht werden müssen, dann ist der FULLTEXT-Index
über alle Spalten wichtiger.
Also brauchst Du tatsächlich _mehrere_ FULLTEXT-
Indizes - und je nach Deinen tatsächlichen WHERE-
Klauseln wird der Optimizer den _besten_ dieser
Indizes auswählen (was Du via EXPLAIN kontrollieren
kannst).

Was auffällt, so allgemein auch, das schlimmste ist
order by, die Where-Bedingungen machen fast nichts
aus, machmal wird es sogar noch schneller, und instr
() macht nichts aus! Kannst Du aber gerne widerlegen
;-)

ORDER BY ist eine n * log(n)-Operation auf der Menge
aller Treffer (weil kein Index dafür verwendet wird).
Dieser Kostenfaktor explodiert mit großen Trefferzah-
len überlinear, während alle anderen Faktoren linear
bleiben.

Gib eine Meldung aus: "Diese Suche erzeugte zu
viele Treffer - bitte geben Sie exaktere
Suchbegriffe an", wenn Dein Limit erreicht wurde.
Auch später in der Praxis? Newbies verstehen sowas
sehr schlecht! Aber wäre vielleicht mal ein Weg die
dazu zu bringen ;-)

Genau. Deine Suche _kann_ sehr schnell werden.
Wer damit nicht umgehen kann, hat die Möglichkeit,
eines von mehreren Alternativprodukten zu nutzen -
eines davon heißt Google mit dem Term
      "site:forum.de.selfhtml.org".
Und die kannst Du alle in Deinem Formular verlinken. ;-)

Vielen Dank nochmal für die große Hilfe, ist
jedesmal spannend Deine Postings zu lesen!

Über Dein aktuelles Problem zerbreche ich mir seit
mehr als einem Jahr meinen Kopf, in verschiedenen
Ausprägungen - sowohl auf das Self-Portal bezogen
als auch hier im Büro.

Die Idee, bei der Self-Suche mit FULLTEXT zu arbeiten,
ist schon fast ein Jahr alt (damals habe ich mit mei-
ner Nachrichtensuche angefangen).
Die Einschränkung auf "mindestens 4 Zeichen Wortlänge"
etc. war damals von Christian als k.o.-Kriterium be-
trachtet worden - in der Zwischenzeit wissen wir aber,
wo man das im mySQL-Source ändern kann (mir hätte es
auch nicht gereicht - ich mußte auf 3 Zeichen runter,
sonst kann man nicht nach DAX, BMW, MLP etc. suchen).

Viele Grüße
      Michael