Andreas Korthaus: Suche online(funktionsfähig) / Perfromance-Verbesserungen?

Beitrag lesen

Hi

Dann ist Deine Maschine offenbar doch ziemlich langsam.

Lag daran, das ich gleichzeitig mit WGET die Daten gezogen habe und evtl. gerde noch ein andere Index geschrieben wurde, das konnte ich nicht abbrechen, weiß es aber nicht. Ist schon tierisch lahm! Wenn ich in die bestehende Tabelle jetzt einen Monat mit ca. 3000 Datensätzen einfüge, dauert das merh als 30 Minuten, ohne Index geht das unter 1 Minute!

Meine Erfahrungen stammen allerdings von einem SUN- Server mit 4 GB RAM und mehreren CPUs ... der schlägt sich bei dieser Aufgabenstellung großartig.

Ja, das ist kein Wunder! Ich habe eien AthlonXP 2000 und 256 MB DRR RAM, da sollte ich bei gelegenheit mind. 256 MB hinzufügen, besser direkt auf 1 GB, aber das ist gar nicht billig!

Wieviel RAM hast Du mySQL zugeordnet?

Gar nichts, zumindest nicht bewußt. Wo kann an das machen? In MYSQL, oder in Linux selbst? Was ich gefunden habe:

key_buffer_size                   8388600 bdb_cache_size                    8388600

myisam_sort_buffer_size           8388608 record_buffer                      131072 record_rnd_buffer                  131072 sort_buffer                       2097144 table_cache                            64

max_allowed_packet               16777216 net_buffer_length                   16384 select_limit                         1000

War das alles oder gibts da noch interessante Dinge? Wie sollte ich diese Werte in diesem Fall verändern, um eine optimale Performance für die gestellten Anforderunegen zu erreichen?

Sowas habe ich in der Doku gesehen: shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k
           -O record_buffer=100k &

Was hälst Du davon? Wieso habe ich nue saf_mysqld und nicht einfach mysqld als Dämon? Hat das was zu sagen? Hab mir das Kapitel von wegen Performance auch mal durchgelesen, aber habe nicht wirklich alles verstanden. Und wie ich es auch sehe kann man mit anders kompilieren... unter Linux eh nicht mehr so viel rausholen, wichtiger wäre es eine optimale Datenstruktur und optimale Abfragen zu bekommen, und das ist IMHO nicht leicht!

Wie groß ist die Indexdatei, die für Deine Tabelle erzeugt werden muß? Wenn diese nicht in den RAM paßt, wird die Sache sehr viel langsamer.

Welche Index-Datei jetzt? Es werden ja merhere Dateien zu einer Tabelle angelegt, und die Tabelle hat jetzt schon über 100 MB, dazu kommt ein 60MB Index, nur Fulltext und Primary. Ach ja, hat das vielleicht was mit tmp_table_size=33554432 zu tun?

Hast Du /ver/tmp auf einer RAM-Disk liegen?

Du meinst /var/tmp? Da ist eine Datei namens test.php.swp drin, sonst nichts! Das ganze liegt auf meiner normalen Festpkatte, wie beschrieben, ich habe 2, eineneuere (60GB ATA100/5400) und eine 4GB, auf der ich komplett Linux untergebracht habe. 10 GB von der Windows Festplatte habe ich in FAT32 umpartitioniert und in /mnt/windows gemountet, nutze das aber bisher nur zum Datenaustausch. Ich überlege aber, da mit 4 GB für Windows auch zu wenig ist, ob ich nicht noch eine bessere Platte kaufe, so eine ATA 133 mit 7200 UPM und Zugriffzeiten unter 8 ms,das wäre hier glaube ich angebracht, dann halt weniger Speicher, das würde wohl zu teuer. Dazu noch ein wenig RAM, dann sollte das ganze etwas besser laufen!

Hast Du mal mit iostat gemessen, ob Du während eines lesenden Zugriffs auf den FULLTEXT-Index Schreibzu- griffe (!) auf eine Festplatte hast?

Wer oder was ist "iostat"? Kenne ich nicht und es ist nichts mit dem Namen installiert. Außerdem sind die lesenden Zugriffe sehr schnell, da kann ich kaum gleichzeitig schreiben und das noch messen... wie geht das? Was ich sagen kann, wenn ich viele Inserts mache(in einer Schleife 3000 Stück mit Index schreiben) kann ich gleichzeitig lesen, dauert nur extrem lange, hatte mal 80 Sekunden, das war aber nur während ein Index generiert wurde.

Dazu müßtest Du eine entsprechende Messung machen. Du kannst natürlich in die Posting-Spalte einen belie- bigen String Eintragen - da dürfen auch die anderen zu indexenden Felder drin stehen, da Du ja später nicht den eigentlichen Inhalt des Thread aus dieser Spalte füttern, sondern statt dessen auf das Original linken wirst.

Das ist halt komisch, ich kann da überhaupt gar keinen roten Faden finden. Mal dauert das 0,03 und  mal 13. Aber das kommt auch daher, da ich den Index so extrem bearbeite, halt immer viele neue Datensätze... jetzt ist es wieder ganz schlecht nachdem ich jetzt alles bis 03 eingefügt habe, daher werde ich jetzt den Index löschen(hat nur gut 1 Minute gedauert?!) und neu erstellen. Also ich habe jetzt um 19:40 gestartet, mal schaun wie lange das mit 100MB Daten dauert. Habe den Index jetzt etwas verändert, habe das ein wenig so wie bei anderen indices gemacht, die wichtigen Feld rnach vorne nicht unbedingt den kompletten Body, des Threads, vielleicht hilft das ja was. ALTER TABLE selfarchiv ADD FULLTEXT KEY body (topic,title,name,body) Mit Explain habe ich jedenfalls festgestellt, dass Fulltext immer verwendet wird. Was ich nur nicht weiß, ich habe das Gefühl, normal der Fulltext Index und dessen Abfrag ist sehr schnell, wie ist es denn wenn ich "normale WHERE-BEdingungen damit kombiniere, so wie ich das zur Zeit mache, ist das perfromance-mäßig egal? Oder sollte ich lieber mehrere Fulltext-Indices und die dann abfragen? Ich habe in der Tat ein Problem damit vergleichbare Daten zu bekommen. Die gleiche Abfrage kann 100 mal so lange dauern, k.A. warum. Halt wenn der Index diffus ist und das System durch andere Prozesse etwas ausgelastet ist, vielleicht ist auch die kleine Platte fast voll... ich weiß es nicht.

btw, kennst Du einen Befehl der einem anzeigt wieviel Platz noch auf einer Platte/Partition zur Verfügung steht, möglichst in Byte?

Das kommt darauf an, wie Du auf ihn zugreifst. Eine normale relationale Datenbank kann pro Query nur einen einzigen Index nutzen - und das wird bei Dir immer der FULLTEXT-Index sein, sofern ein Suchbegriff angegeben war (und Suchvorgänge ohne Suchbegriff sind in Deinem Konzept derzeit ja wohl nicht vorgesehen).

Und man verwendest immer nur einen Index? Man könnte denselben Index mit mehreren Wörtern ja auch mehrmals abfragen, also wenn ich möchte das 2 Wörter enthalten sind, dann sowas wie

$suchstring = "wort1+wort2";

$query = SELECT... WHERE"; foreach(explode("+",$suchstring) as $suchwort){     $query .= " match... against($suchwort)"; } mysql_query($query);

So in etwa, was sagst Du dazu? Aber wie gesagt, ich will undbedingt MySQL4 probieren, denn gerade darauf habe ich mich schon lange gefreut ;-) Und gerade dieses geht in MYSQL 4 erheblich besser!

Mittelfristig will ich auch eine Art "Archiv-Browser" schreiben, naja, Browser ist das falche Wort, ich möchte nur, das man das Archiv auch manuell durchsuchen kann, ohne die chronolog. Liste.

Und halt mal ein Ranking, dazu würde ich gerne 4 Dinge miteinbeziehen:

  1. einen eigenen Ranking-Algorithmus für die Threads oder Postings, allggemein
  2. die Vielposterstatistik, ich weiß, hört sich dumm an, aber wenn viele Leute aus den oberen Regionen in einem Thread schreiben ist der meist sehr interessant, warum also nicht diese Information für ein Ranking nutzen???
  3. Gesamtvorkomen der Suchworte Im Thread,
  4. höhere Gewichtung des Titels
  5. Noch höhere gewichtung der Kategorie
  6. Vorkomman im Athoren-Feld
  7. Die Zeit, neuere Threads ein wenig besser bewerten

Und vielleicht eine Checkbox"ich habe in dem Thread gepostet", wenn man das später mit einem Forum-Login verbindet wäre das zumindest für mich ganz interessant!

Deshalb bringen weitere Indexe bezüglich der Lese- performance erst mal nichts - wenn mySQL durch den FULLTEXT eine Tabellenzeile ausgewählt hat, kann es relativ schnell deren Inhalt abgreifen und darin das Feld mit dem Themenbereich prüfen.

Das Problem bei Fullteyt besteht unter anderem auch darin, dass wenn ich sortieren will und die Abfrage ein Limit enthält kommen da je nach Sortiereung, ganz anderer Daten bei raus!

mySQL 4.0 kündigt mir nichts an, was die Funktionalität oder Architektur Deiner Suche signifikant ändern würde.

Das habe ich jas schon geschrieben:

  1. Geschwindigkeit
  2. boolsche Verknüpfungen und was da noch so stand. Konnte man hier nicht auch irgendwo den Minimum-Wert für Suchwörter von 4 verändern? Das ist doch schon nicht schlecht! Außerdem ist der Index flexibler, vielleicht bekommt man so ja doch ein besseres Ranking.

Lies mal im mySQL-Handbuch nach, wie diese Relevanz berechnet wird.

hab ich, das ganze ist eher auf eine allgemeine Suchmaschine ausgerichtet, in der man eine kurze Information sucht!

Wie würdest Du es tun, wenn Du gar keine Ahnung hast, was die Postings bedeuten? Über die relative Häufigkeit des Wortes innerhalb des Textes. Und die ist bei kurzen Postings natürlich höher als bei langen. Ergo: Verwirf diese Idee, sie bringt Dich hier nicht weiter.

Aber wenn ich ein Limit in der Abfrage einfüge, und einfach wahllos Datensätze zurück bekomme, halt wenn mehr als das Limit gefunden werden, dann ist das doch wirklich "ungünstig"!

Schreib Dir ein Konzept dafür. Ignoriere völlig, wie Du es implementieren müßtest.

Das mache ich immer gleichzeitig, sollte ich nicht machen, aber da meien EDV-Kenntnisse noch immer recht beschränkt sind, kann ich nicht sagen "alles ist möglich"!

Definiere eine "gute" Ranking-Funktion. Wie man diese dann umsetzt, soll Dich vorerst nicht interessieren.

Wenn ich das alleine mache schon ;-)

Und welche Worte würdest Du auf diese Stopwortliste setzen? Ich habe mir dafür ein Konzept ausgedacht - das ist aber auf meine Art von Daten bezogen.

Das weiß ich auch nicht. Wäre es eigentlich nicht viel schlauer, diese orte anstat mit einem Stop-Word-Liste zu filtern, diese zu entfernen? Das sollte kein Problem sein und könnte die Suche entlasten. Problematischer wird es dann wieder bei der Phrasensuche, ob sich das kombinieren läßt? Aber das schlimmste ist die Beschränkung auf Worte über 3 Buchstaben! Gerade "PHP", "SQL"... lassen sich so nur schlecht finden, halt nur so wie ich es jetzt gemacht habe, aber da wird ja dann auch nur die Themen-Spalte durchsucht.

Poste doch mal die exakten SQL-Statements. Und schalte die Verwendung der impliziten Rating-Funktion ab

Wie denn? Ich dachte MySQL macht das von alleine? Daher habe ich auch Ranking als Standard, chronologisch ist mehr Arbeit, da das Order By noch dazu kommt. Die Relevanz wid doch immer ausgerechnet, wie soll ich das abschalten?

Danach lasse Dein CGI-Frontend dynamisch bestimmen, welche der beiden Datenbanken gerade die aktuelle ist - es reicht, wenn Dein Indexer ein stub file entsprechend setzt.

Was meinst Du mit "stub file"? Eine Datei in die Du den Status schreibst, welche DB gerade verwendet wird?

Ich selbst verwende dies an einer anderen Stelle, wo ich tatsächlich die Indexe täglich neu baue (mit noch viel mehr Einträgen, fast 20 Millionen Stück). Bei dem, was Deiner Posting-Suche ähnlicher ist, indexe ich aber inkrementell - und verbrauche täglich bei 5000 neuen 'Postings' nicht mal eine CPU-Minute.

Womit kann man solche Daten gut messen? Ich habe da zwar einen grafischen Systemmonitor, aber der ist nicht der Hit.

Deine Suche muß schon beim ersten Zugriff schnell sein. Du kannst nicht erwarten, daß die Anwender ähnliche Suchbegriffe eingeben - und Dein RAM ist auch sehr begrenzt.

Wie kann ich denn den Cache so groß wie möglich bekommen? Und wie kann ich das objektiv testen, wenn der ich jede meiner Suchen merkt und bei den einen Sachen besser, und bei den anderen Sachen erheblich schlecht wird, und dann noch bei ungleicher Verteilung der Wörter...

Grüße Andreas