SELFSUCHE II / Parsing-Problem
Andreas Korthaus
- programmiertechnik
Hallo!
Ich hatte heute mal ein bisschen Lust eien Suche zu programmieren, dabei ts folgendes rausgekommen: http://selfarchiv.d2g.com/
ich hoffe das stört keinen, funktioniert auch mehr schlecht als recht, habe mir das Archiv von September mal gzippet runtergeladen(7 MB), und geparst und in eine MySQL Db gechireben, beim Parsen ist aber mächtig was schiefgelaufen, denn dekomptimiert sind es nur knapp 5 MB in der DB ;-) Ist M;ySQL 3.23 mit Fulltext-Index über Thema, Titel und Body. Solte auch nach relevanz sortieren, aber nur so wie es implementiert ist, naja. Falls also die Suche nochmal nicht geht... ;-)
Aber wie gesagt ist nur 9/2002 und nur eingeschränkt nutzbar. Ich versuche das mal zu verbessern, vielleicht auch mit MySQL 4, mal sachauen. Die Threads habe ich nicht, die sind nur verlinkt.
probleme habe ich beim bearbeiten des Quellcodes, aus mir bislang nicht erklärlichen gründen funktioniert es einfach nicht(immer) die html-tags zu entfernen.
Gerade bei längeren Threads, wie http://forum.de.selfhtml.org/archiv/2002/9/22236/. Wenn ich diese Datei in PHP durch strip_tags laufen lasse, dann wird mir nic der String bis
[...]
(MEINUNG) Wenn ich das schon höre: "Bevorzugung der Reichen" von
Martin Speiser, 02. 09. 2002, 14:55 Uhr (MEINUNG) Wenn ich das schon höre:
"Bevorzugung der Reichen" von Bio, 02. 09. 2002, 16:41 Uhr (MEINUNG) Wenn ich das schon höre: "Bevorzugung der Reichen" von Martin Speiser, 02. 09. 2002, 19:16 Uhr (MEINUNG) Wenn ich das schon höre: "Bevorzugung der Reichen" von Bio, 02. 09. 2002, 20:50 Uhr (MEINUNG) Wenn ich das schon höre
zurückgegeben, es ist einfach Schluß! Und das schon oben in der Baumstruktur. Was sollen da bitte für Zeichen reinkomen die da was durcheinander bringen?
Ich habe es auch it deem Original-Quellcode versucht - schafft das jemand die html-tags aus oben angegebener Quelle zu entfernen? Ich probiere das jetzt gleich 2 Stunden lang, und habe alle erdenklichen Möglichkeiten (preg_preplace("/<(.*?)>/","",$input)...) probiert, alle Komentare probiert.... nichts hilft. Es wird immer an derselben Stelle abgebrochen. Was mache ich falsch?
Viele Grüße
Andreas
Moin!
Gerade bei längeren Threads, wie http://forum.de.selfhtml.org/archiv/2002/9/22236/. Wenn ich diese Datei in PHP durch strip_tags laufen lasse, dann wird mir nic der String bis
strip_tags() ist eine recht böse Funktion. Die löscht nämlich alles, was zwischen einem < und einem > steht, vollkommen unabhängig davon, ob es nun wirklich ein Tag ist oder nicht. Da zum Glück anzunehmen ist, dass < und > hier entweder maskiert sind oder zum HTML gehören, kommst du noch einmal davon (schlecht ist diese Funktion bei Usereingaben, die möglicherweise HTML enthalten könnten - da wird unter Umständen zuviel gelöscht).
[...]
(MEINUNG) Wenn ich das schon höre: "Bevorzugung der Reichen" von
Martin Speiser, 02. 09. 2002, 14:55 Uhr (MEINUNG) Wenn ich das schon höre:
"Bevorzugung der Reichen" von Bio, 02. 09. 2002, 16:41 Uhr (MEINUNG) Wenn ich das schon höre: "Bevorzugung der Reichen" von Martin Speiser, 02. 09. 2002, 19:16 Uhr (MEINUNG) Wenn ich das schon höre: "Bevorzugung der Reichen" von Bio, 02. 09. 2002, 20:50 Uhr (MEINUNG) Wenn ich das schon höre
zurückgegeben, es ist einfach Schluß! Und das schon oben in der Baumstruktur. Was sollen da bitte für Zeichen reinkomen die da was durcheinander bringen?
Keine Ahnung, was da schiefläuft. Offen gesagt habe ich auch gerade nicht die Lust zum Selbersuchen. Ich geh' lieber gleich mal durch die neue Elbtunnelröhre. ;)
Ich habe es auch it deem Original-Quellcode versucht - schafft das jemand die html-tags aus oben angegebener Quelle zu entfernen? Ich probiere das jetzt gleich 2 Stunden lang, und habe alle erdenklichen Möglichkeiten (preg_preplace("/<(.*?)>/","",$input)...) probiert, alle Komentare probiert.... nichts hilft. Es wird immer an derselben Stelle abgebrochen. Was mache ich falsch?
Versuchs einfach mal manuell und füttere dein Skript damit. Wenns immer noch schiefläuft, liegt es nicht an den Tags.
- Sven Rautenberg
Hallo!
strip_tags() ist eine recht böse Funktion. Die löscht nämlich alles, was zwischen einem < und einem > steht, vollkommen unabhängig davon, ob es nun wirklich ein Tag ist oder nicht. Da zum Glück anzunehmen ist, dass < und > hier entweder maskiert sind oder zum HTML gehören, kommst du noch einmal davon (schlecht ist diese Funktion bei Usereingaben, die möglicherweise HTML enthalten könnten - da wird unter Umständen zuviel gelöscht).
Ja, da hatten wir schonmal drüber diskutiert, aber soweit ich weiß ist es im Selfforum nicht möglich eigene <> in den HTML-Quellcode zu bekommen, doer? Also sollte es gehen, oder? Irgendwie muß ich den Code ja rausbekommen! Daher filtere ich erst die Basisdaten aus dem Thread(Thema, User, zeit), dann entferne ich die html-tags, und dannach wandele ich html-entitäten um.
So komme ich auf ca. 12 MB pro Monat, was in etwa mit dem Archiv übereinstimmt. Habe jetzt mal die letzten 4 Monate in der Datenbank(50MB Daten, 40 MB Index ;-))
Ich habe jetzt 3 Stunden lang versucht MySQL 4 zu installiern, was an sich nicht schwer war, aber ich habe es nicht fetiggebraucht aus PHP darauf zuzugreifen, vielleicht braucht man ein anders Modul? k.a., aber das probiere ich irgendwann sicher nochmal, denn gerade für Volltext-Suche ist die 4er erheblich besser.
Keine Ahnung, was da schief läuft. Offen gesagt habe ich auch gerade nicht die Lust zum Selbersuchen. Ich geh' lieber gleich mal durch die neue Elbtunnelröhre. ;)
Lag daran, das durch die Komprimierung bei langen Dateien irgendwie Zeilenumbrüche reingekommen sind, die ich nicht erwartet habe, und so habe ich immer nur den Teil bis zum ersten Zeilenumbruch gehabt... ich denk jetzt ist mein "Archiv-parser" funktionsfähig.
Was ich gemerkt habe, der Index muß immer aktuell sein, wenn ich ein paar 1000 Datensätze in die Tabelle schreibe, wird die Suche erheblich langsamer. Ich habe jetzt ca. 12.000 Datensätze in der DB(1 pro Thread), und da dauert es mehr als 15 Minuten den Index neu zu erstellen! Auch wenn ich eine kompletten Dump im batch-modus einlese!
Und die ganze Zeit ist die CPU und der Arbeitsspeicher bis zum Anschlag ausgelastet! Ich denke daher das mehr CPU-Power und vor allem RAM sehr wohl was bringt! Kann man nie genug haben, zumindest solange das System drauf ausgereichtet ist. Wie pflegt Ihr denn solche Indices?
Die Datenbank lasse ich jetzt auch mal online, würde mich mal interssieren was Ihr davon haltet.
Die Tabelle hat folgende Struktur:
CREATE TABLE selfarchiv (
id smallint(6) NOT NULL default '0',
topic varchar(20) NOT NULL default '',
title varchar(100) NOT NULL default '',
body text NOT NULL,
name varchar(40) NOT NULL default '',
time int(10) NOT NULL default '0',
PRIMARY KEY (id),
UNIQUE KEY id (id),
FULLTEXT KEY body (body,topic,title)
) TYPE=MyISAM;
Wobei ich glaube ich auf unique und Primärschlüsel verzichten kann, denn das bringt hier eh nichts. Die Gewichtung ist aber nicht das gelbe vom Ei. Das ist noch viel zu unflexibel. Außerdem ist das Verhätnis nicht ganz richtig. Ich hatte mir folgendes überlegt, um dem Titel und dem Themenbereich mehr Gewicht zu verleihen:
entweder ich füge eine weiter Spalte ein, und hier dann duch Leerzeichen getrennt 5 mal das Thema und 10 mal den Titel, und das dann mit in den Index aufnehmen, oder 15 weiter Spalten mit entsprechend 5 mal Titel und 10 mal Themenbereich.
Ich habe auch schon ein eine eigene stop-word Liste gedacht, indem ich beim Anlegen der Datensäzte dort ausgewiesene Wörter entferne.
Wobei ich gestehen muß, Ihr hattet Recht, so viel schneller ist die DB auch nicht, aber auf der anderen Seite habe ich keine Ahnung wie man das ganze wirklich performant macht, da gibt es ja glaube ich noch einige Möglichkeiten...
Das Parse-Script ist übrigens ziemlich simpel, ich habe das so gelöst:
$handle=opendir($path);
while ($dir = readdir ($handle)) {
if ($dir!= "." && $dir != "..") {
$id = $dir;
$html = gzfile($path.$dir."/".$filename);
if(isset($html[1])) {
$data = implode(" ",$html);
}
else {
$data = $html[0];
}
preg_match("/((.*?))(.*?)<meta name="description" content="SELFHTML-Forumsarchiv, Thread: (.*?)">(.*?) von <b>(.*?)</b>, ([0-9]{2}). ([0-9]{2}). ([0-9]{4}), ([0-9]{2}):([0-9]{2}) Uhr/",$data,$basic_data);
$data = urldecode(strip_tags($data));
$trans = get_html_translation_table (HTML_ENTITIES);
$trans = array_flip ($trans);
$data = strtr($data,$trans);
preg_match ("/ (.*) /",$data,$matches);
$data = $matches[1];
query("
INSERT INTO selfarchiv
SET id = ".$id.",
topic = '".mysql_escape_string($basic_data[1])."',
title = '".mysql_escape_string($basic_data[3])."',
body = '".mysql_escape_string($data)."',
name = '".mysql_escape_string($basic_data[5])."',
time = UNIX_TIMESTAMP('".$basic_data[8]."-".$basic_data[7]."-".$basic_data[6]." ".$basic_data[9].":".$basic_data[10].":00')
");
}
}
closedir($handle);
Mal ne ganz andere Frage: Wo kann ich unter Linux einstellen, welche Programe beim Starten geladen werden? Also mein dyndns client z.B.? den starte ich jetzt immer manuell aus der shell, das kann es ja nicht sein!
Viele Grüße
Andreas
PS: Meine Suche funktioniert im Prinzip(für Anwender) genaus so wie die originale, es wird halt nur etwas anders sortiert, und ich zeige nur einen Datensatz pro Thread an, und nicht pro Posting. Das war jetzt einfacher. Vielleicht als Notlösung wen die Self-Suche lahmt ;-)
Moin!
Was ich gemerkt habe, der Index muß immer aktuell sein, wenn ich ein paar 1000 Datensätze in die Tabelle schreibe, wird die Suche erheblich langsamer. Ich habe jetzt ca. 12.000 Datensätze in der DB(1 pro Thread), und da dauert es mehr als 15 Minuten den Index neu zu erstellen! Auch wenn ich eine kompletten Dump im batch-modus einlese!
Du hast sicher in der Doku gelesen, dass es schneller geht, die Tabelle zunächst ohne Volltext-Index anzulegen und zu befüllen, und den Index erst nachträglich hinzuzufügen, oder?
Und die ganze Zeit ist die CPU und der Arbeitsspeicher bis zum Anschlag ausgelastet! Ich denke daher das mehr CPU-Power und vor allem RAM sehr wohl was bringt! Kann man nie genug haben, zumindest solange das System drauf ausgereichtet ist. Wie pflegt Ihr denn solche Indices?
Klar bringt vor allem viel RAM viel, weil die ganzen Indices sich nun mal viel besser im RAM machen, als auf Festplatte.
Wobei ich glaube ich auf unique und Primärschlüsel verzichten kann, denn das bringt hier eh nichts. Die Gewichtung ist aber nicht das gelbe vom Ei. Das ist noch viel zu unflexibel. Außerdem ist das Verhätnis nicht ganz richtig. Ich hatte mir folgendes überlegt, um dem Titel und dem Themenbereich mehr Gewicht zu verleihen:
entweder ich füge eine weiter Spalte ein, und hier dann duch Leerzeichen getrennt 5 mal das Thema und 10 mal den Titel, und das dann mit in den Index aufnehmen, oder 15 weiter Spalten mit entsprechend 5 mal Titel und 10 mal Themenbereich.
Das bringt beim MySQL-Volltextindex aber leider genau das Gegenteil. Je häufiger ein Wort vorkommt, desto weniger relevant ist es, und desto geringer die Ergebnisgewichtung. Dein Vorhaben könnte zur Folge haben, dass man nichts mehr findet.
Wenn du Titel, Thema und Postingtext unterschiedlich gewichten willst, dann mach drei statt einen Volltextindex (wobei der Themenbereich eher _keinen_ Volltextindex benötigt, denn da ist die Auswahlmöglichkeit ziemlich gering).
Bedenke auch, dass du bei einer Abfrage über den Volltextindex eine Relevanzangabe erhälst, die du nutzen kannst. Beispielsweise könntest du die Relevanz der Titelfunde entsprechend multiplizieren und dann die Relevanz der Postingfunde addieren, um eine Gesamtrelevanz zu erhalten (und danach zu sortieren - macht ja alles mySQL für dich, wenn du willst).
Ich habe auch schon ein eine eigene stop-word Liste gedacht, indem ich beim Anlegen der Datensäzte dort ausgewiesene Wörter entferne.
Bringt auch nichts in Verbindung mit dem Volltextindex. Da werden häufig vorkommende Wörter automatisch zu Stop-Wörtern, die man über den Index nicht mehr findet.
Wobei ich gestehen muß, Ihr hattet Recht, so viel schneller ist die DB auch nicht, aber auf der anderen Seite habe ich keine Ahnung wie man das ganze wirklich performant macht, da gibt es ja glaube ich noch einige Möglichkeiten...
Aha! :) Wie du siehst, ist auch eine Datenbanklösung nicht endlos überlegen - mehr Performance kriegt man also nur über schnellere oder parallele Maschinen. Wobei es IMO etwas Overkill ist, nur für die Archivsuche eine eigene Maschine hinzustellen, die dann auch noch regelmäßig die neuen Archiveinträge mitgeteilt bekommen muß. Google zieht sich da relativ leicht aus der Affäre, weil dort in regelmäßigen Abständen Updates der Suchdatenbank auf die Cluster verteilt werden. Die Zeitabstände sind aber wohl monatlich - für die Archivsuche unzumutbar!
Mal ne ganz andere Frage: Wo kann ich unter Linux einstellen, welche Programe beim Starten geladen werden? Also mein dyndns client z.B.? den starte ich jetzt immer manuell aus der shell, das kann es ja nicht sein!
Unter /etc/rc.d/ sind diverse Skripte, die Startaufgaben erledigen (kann sein, dass der Pfad Suse-geschädigt ist und normalerweise auf /sbin/init.d/ lautet). Weiterhin befinden sich in diesem Verzeichnis einige Unterverzeichnisse rcX.d (für das X eine Ziffer), in denen sich symbolische Links auf die Skripte befinden. Die Namensgebung ist einheitlich: K - Kill-Skript, stoppt einen Dienst, wenn der Runlevel (die Ziffer im Verzeichnisnamen) verlassen wird. S - Start-Skript, startet den Dienst. Die nachfolgende Zahl gibt an, in welcher Reihenfolge die Skripte abgearbeitet werden. Dein DynDNS-Skript sollte sinnvollerweise erst dann gestartet werden, wenn dein Netzwerk gestartet ist, und gestoppt werden, bevor dein Netzwerk stoppt.
Mein Skript für DynDNS heißt "ddclient" und ist im Runlevel 2 (nur Kommandozeile - was brauch ich X auf einem Server) mit S25ddclient und K09ddclient verknüpft. Wird als ziemlich zum Schluß gestartet (nach S25 kommt bei mir nicht mehr viel), und ziemlich zum Anfang gestoppt (K09 ist das erste Skript).
- Sven Rautenberg
Hallöchen!
Du hast sicher in der Doku gelesen, dass es schneller geht, die Tabelle zunächst ohne Volltext-Index anzulegen und zu befüllen, und den Index erst nachträglich hinzuzufügen, oder?
Muß ich überlsen oder vergessen haben, jedenfalls bin ich dann auch selbst auf den trichter gekommen, nachdem bei Datensatz 4000 das ganze mehr als 1 Sekunde pro Datensatz dauerte - mit sinkender Tendenz ;-)
Aber auch das nachträgliche erstellen dauer bei 12.000 Datensätzen und ca. 50 MB mehr als eine Halbe Stunde, das Nadelöhr ist ganz klar mein RAM, 256 ist deutlich zu wenig. Interesant was man unter Linux so alles "momitoren" kann ;-)
Klar bringt vor allem viel RAM viel, weil die ganzen Indices sich nun mal viel besser im RAM machen, als auf Festplatte.
Und die 2. Sache ist das ich für Linux meien uralte 4GB Festplatte verwende, vermutlich mit tierischen Ansprechzeiten, Drehzahl und mit 66er FSB..., ausßerdem Rattert die so, muß glaube ich mal tauschen :) Wobei Linux rtrotzdemnoch erheblich schneller ist als Windows2K!
Das bringt beim MySQL-Volltextindex aber leider genau das Gegenteil. Je häufiger ein Wort vorkommt, desto weniger relevant ist es, und desto geringer die Ergebnisgewichtung. Dein Vorhaben könnte zur Folge haben, dass man nichts mehr findet.
Stimmt, das hatt eich nur irgendwie im Kopf, war abr glaube ich mal angedacht gewesen, wenn man das ihne Fulltext, sondern manuell löst.
Wenn du Titel, Thema und Postingtext unterschiedlich gewichten willst, dann mach drei statt einen Volltextindex (wobei der Themenbereich eher _keinen_ Volltextindex benötigt, denn da ist die Auswahlmöglichkeit ziemlich gering).
Sehr gute Idee. Sollte man denn nicht lieber die Indices zusammenlegem, ich meine jetzt im allgemeinen, oder lieber enzelnde?
Aber warum braucht der themenbereich keien Volltxt-index? Die "navigation" durch alte Beiträge ist IMHO sehr verbesserungswürdeig, die Archivdateien sind_viel_ zu unübersichtlich, und die Suche nur chronologisch. Ich denke hier könnte man doch was draus machen, natütlich nicht mit den Standards von mySQL 3.23, aber so allgemein! Vielleicht kombiniert mit einem BEwertungssystem, aber dsas hatte wir ja schonmal ;-)
Auf alle Fälle muß das Archiv mal etwas strukturiert werden, udn am besten noch die Namen genannt werden, damit man die Beiträge aucgh 3 Wochen später noch halbwegs zuordnen kann! Wenn die Suche nicht geht ist man total aufgeschmissen, oft weiß ich in welchem Thread die Lösung meines Problems steht, komme aber nicht dran(jetzt schon ;-))!
ich probier emal ein bisschen rum, vielleicht bekome ich ja mal ne gute _und_ praktikable Idee ;-)
Bedenke auch, dass du bei einer Abfrage über den Volltextindex eine Relevanzangabe erhälst, die du nutzen kannst. Beispielsweise könntest du die Relevanz der Titelfunde entsprechend multiplizieren und dann die Relevanz der Postingfunde addieren, um eine Gesamtrelevanz zu erhalten (und danach zu sortieren - macht ja alles mySQL für dich, wenn du willst).
Ja, das ist wirklich gut. Nur was mich stört, die kleinen Beiträge, mit wenig drin stehen ganz oben, das ist IMHO falsch! Man bräuchte noch ein Feld mit der Länge des Threads. Vielleicht noch verknüpüft mit der Vielosterstatistik, um mit einem Allgorythmus ein kleines Ranking hinzubekommen, warum eigentlich nicht? WI egesagt, wenn denn MySQl 4 mal bei mir funktioniert, probier ich da mal einiges...
Von mir aus kann ich die Adresse auch so lassen, dann teste ich auf einer anderen Seite, udn wenn die Suche mal ausfällt hätte man trotzdem noch eine - wenn auch schwache - Aussicht auf Erfolg ;-) Ich baue da gleich noch ein paar Kleinigketen ein, und will das gesamte Archiv 2002 eintragen. Dann brauche ich noch nen Cronjob der Aktuelle Beitäge abfragt und fertig ist das ertmal.
Ich habe auch schon ein eine eigene stop-word Liste gedacht, indem ich beim Anlegen der Datensäzte dort ausgewiesene Wörter entferne.
Bringt auch nichts in Verbindung mit dem Volltextindex. Da werden häufig vorkommende Wörter automatisch zu Stop-Wörtern, die man über den Index nicht mehr findet.
Aber mydql hat doch auch eine statische Liste, udn die iszt englische. Ich meine nur hierfür als Pendant!
Wobei ich gestehen muß, Ihr hattet Recht, so viel schneller ist die DB auch nicht, aber auf der anderen Seite habe ich keine Ahnung wie man das ganze wirklich performant macht, da gibt es ja glaube ich noch einige Möglichkeiten...
Aha! :) Wie du siehst, ist auch eine Datenbanklösung nicht endlos überlegen - mehr Performance kriegt man also nur über schnellere oder parallele Maschinen. Wobei es IMO etwas Overkill ist, nur für die Archivsuche eine eigene Maschine hinzustellen, die dann auch noch regelmäßig die neuen Archiveinträge mitgeteilt bekommen muß. Google zieht sich da relativ leicht aus der Affäre, weil dort in regelmäßigen Abständen Updates der Suchdatenbank auf die Cluster verteilt werden. Die Zeitabstände sind aber wohl monatlich - für die Archivsuche unzumutbar!
Nicht so schnell ;-) Bedenke das ich als "verhältnismäßiger DAU" dies zu stande gebracht habe, Mit Eurem Wissen und den Indice oder ganzen Tabellen im RAM, und noch dies oder das... wird das ganze erheblich schneller. Dann noch die 4er VErsion... was ich merke, wenn ich neue Wörter suche, dauert das meist um 1 Sekunde. Wenn das Wort schonmal gesucht wurde wird es _erheblich_ schneller. So geht das immer weiter(nicht unendlich), aber das ist genau das Gegenteil zu aktuellen Suche. Die funktioniert umso besser, je wenger Leute sie benutzen. Bei der logarithmischen Suche und den Indices ist das was anders, die DB merkt sich jede Suche! Ich bin fest davon überzugt das sich das bei höherer Belastung sehr positiv auswirkt!
Mal ne ganz andere Frage: Wo kann ich unter Linux einstellen, welche Programe beim Starten geladen werden? Also mein dyndns client z.B.? den starte ich jetzt immer manuell aus der shell, das kann es ja nicht sein!
Unter /etc/rc.d/ sind diverse Skripte, die Startaufgaben erledigen (kann sein, dass der Pfad Suse-geschädigt ist und normalerweise auf /sbin/init.d/ lautet). Weiterhin befinden sich in diesem Verzeichnis einige Unterverzeichnisse rcX.d (für das X eine Ziffer), in denen sich symbolische Links auf die Skripte befinden. Die Namensgebung ist einheitlich: K - Kill-Skript, stoppt einen Dienst, wenn der Runlevel (die Ziffer im Verzeichnisnamen) verlassen wird. S - Start-Skript, startet den Dienst. Die nachfolgende Zahl gibt an, in welcher Reihenfolge die Skripte abgearbeitet werden. Dein DynDNS-Skript sollte sinnvollerweise erst dann gestartet werden, wenn dein Netzwerk gestartet ist, und gestoppt werden, bevor dein Netzwerk stoppt.
hm, ich habe beides ;-) Aber ich habe RH. Leider weiß ich nicht genau welches Script jetzt genau die Internet-Verbindung anstößt, außerdem sind das alle komplexe bash-Scripte, soll ich auch so ein Script schreiben??? Und hat das nicht was mit ip-up zu tun? Aber da weiß ich auch nicht wohin :-(
grüße
andreas
http://selfarchiv.d2g.com/
Moin
hehe :)
http://selfarchiv.d2g.com/index.php?suchausdruck=frames&submit=Suche+starten
...
...
...
(viele ... später:)
(Dauer der Suche: 23.974524021149 sec)
Da hast Du ja noch ordentlich was zu optimieren ;)
Aber ne Idee ist es trotzdem :)
Ciao,
Harry
Hi!
hehe :)
http://selfarchiv.d2g.com/index.php?suchausdruck=frames&submit=Suche+starten
...
...
...
(viele ... später:)
Ja, ich hatte das gerade, einfachsten Anfragen haben auf eineml über eine Minute gedauert. Aber ich hatte wohl zuviel geöffnet, ich konnte auch so kaum noch was machen, keine Ahnung weiso. Mal eben alles gekillt was ich nicht wirklich brauchte und schon gings wieder. Also eines habe ich gelernt:
Volltext ust genau das Falsche für so ein Forum ;-) Das beste Rating habe immer die kürzesten und sinnlosesten Postings! Ich habe a jetzt mak ein paar "Features" einhgebaut, aber mit denen hat das keinen Sinn. Ohne ist das eigentlich ganz OK. Vor allem wenn man mehr sucht, dann wirds richtig flott ;-)
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.
(Dauer der Suche: 23.974524021149 sec)
sollte jetzt schneller gehen - wobei ich bei der offiziellen Suche schon erheblich länger vor verschlossenen Türen gestanden habe ;-))) 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!
Ich habe über die Namen einen "normalen" Index erstellt, aber so viel merke ich davon auch nicht.
Da hast Du ja noch ordentlich was zu optimieren ;)
Aber ne Idee ist es trotzdem :)
Hatte einfach mal Lust, habe noch nie ne Suchmaschine progammiert, und wenn ich schon immer mecker dann muß ich halt mal selbst schlechte Erfahrungen machen ;-)
Wer weiß denn, wie man die vernünftigen Postings nach vorne bekommt? Einfach den Index rumdrehen oder was? Das wäre glaube ich das beste! Vielleicht kann man den Index ja tatsächlich "mit seinen eigenen Waffen schlagen"!
Mich würde aber tatsächlich mal interessieren, ob es so wie es jetzt ist annehmnbar ist oder gräßlich langsam! Von meinem PC ist das schwer zu sagen. Wie gesagt, die volle Geschwindigkeit gibt es nur in Standardeinstellung, sobald man die Suche weiter einschränkt kostet das Geschwindigkeit - manchmal zumindest, ich versteh es halt nicht.
Mal an einen DB-Spezialisten, welche Indizierung würde hier denn jetzt wirklch Sinn machen?
Meine sieht zur Zeit so aus:
CREATE TABLE selfarchiv (
id smallint(6) NOT NULL default '0',
topic varchar(20) NOT NULL default '',
title varchar(100) NOT NULL default '',
body text NOT NULL,
name varchar(40) NOT NULL default '',
time int(10) NOT NULL default '0',
PRIMARY KEY (id),
UNIQUE KEY id (id),
FULLTEXT KEY body (body,topic,title),
KEY name (name),
KEY name_2 (name) *ups* ;-))) das war glaub ich der performancefressende Übeltäter!
) TYPE=MyISAM;
Das ist ein Mist das dauert jetzt bestimmt 10 Minuten so nen blöden Index zu löschen!
Ach ja, die dazu gehörige Abfrage sieht so aus:
$query_string = "SELECT id,topic,title,name,time FROM selfarchiv WHERE MATCH (body,topic,title) AGAINST ('".mysql_escape_string($_GET['suchausdruck'])."')";
if($_GET['Verfasser']) {
#$query_string .= " AND name = '".mysql_escape_string($_GET['Verfasser'])."'";
$query_string .= " AND INSTR(name,'".mysql_escape_string($_GET['Verfasser'])."')>0";
}
if($_GET['Kategorie']) {
$query_string .= " AND topic = '".mysql_escape_string($_GET['Kategorie'])."'";
}
if($_GET['Listing']=="chronologisch"){
$query_string .= " ORDER BY time DESC";
}
$query_string .= " LIMIT 0, $limit";
Kurze Erklärung noch:
Verfasser ist immer der Vrfasser des Startpostings
der Rest sollte klar sein, bis darauf das das Ranking irgendwie gegensätzlich funktioniert ;-)
http://selfarchiv.d2g.com/
Grüße
Andreas
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! Und der blöde index ist immer noch da...und immer noch...
Hallo,
PRIMARY KEY (id),
UNIQUE KEY id (id),
'Primary key' bedingt 'unique'.
Gruesse,
CK
Hi!
'Primary key' bedingt 'unique'.
Danke Dir!
Was anders, ich habe das 2002er Archiv jetzt fast komplett vom Server gezogen, komprimiert mit wget 1.82. Ich weiß, das erzeugt immer ein wenig Overhead, ist aber trotzdem nicht so viel mehr als das komplette Archiv, oder? Waren jetzt immer 5-8 MB pro Monat, und 2000-3000 Dateien. Ich hoffe das hat nicht gestört, aheb das meiste auch zu lastarmen Zeiten gezogen(Sa Nacht, So morgen), und immer mit 1 Sekunde Pause und Bandbreiten-limit.
Heute irgend wann hatt ich auf einmal andere Bilder und css, halt ein Satz von wegen "gehört zu SELFHTML" oder sowas, habt Ihr was dagegen das ich das mache? Jetz ist es wieder normal.
Grüße
Andreas
Hallo,
Was anders, ich habe das 2002er Archiv jetzt fast komplett vom Server gezogen, komprimiert
mit wget 1.82. Ich weiß, das erzeugt immer ein wenig Overhead, ist aber trotzdem nicht so
viel mehr als das komplette Archiv, oder?
Hae?
Heute irgend wann hatt ich auf einmal andere Bilder und css, halt ein Satz von wegen "gehört
zu SELFHTML" oder sowas, habt Ihr was dagegen das ich das mache? Jetz ist es wieder normal.
Ich glaube, das haettest du frueher absprechen sollen. IMHO solltest du sehr deutlich machen,
dass das *nicht* die offizielle Selfsuche ist. Sonst koennten sich einige Leute etwas auf den
Schlips getreten fuehlen.
Gruesse,
CK
Hallo!
Ich glaube, das haettest du frueher absprechen sollen. IMHO solltest du sehr deutlich machen,
dass das *nicht* die offizielle Selfsuche ist. Sonst koennten sich einige Leute etwas auf den
Schlips getreten fuehlen.
Hast Recht, habe das eigentlich nur aus "Spaß an dr Freude" mal probiert, daher habe ich das jetzt ein wenig abgeändert(die Adresse kennt aber eh niemand außer einer Hand voll Leute hier)
<selfarchiv.d2g.com/>
Ist das so OK?
Grüße
Andreas
Hoi,
Hast Recht, habe das eigentlich nur aus "Spaß an dr Freude" mal probiert,
Oh, *ich* hab damit wenig Probleme.
daher habe ich das jetzt ein wenig abgeändert(die Adresse kennt aber eh niemand außer einer
Hand voll Leute hier)
http://selfarchiv.d2g.com/
Ist das so OK?
Kann ich dir nicht sagen, denn:
The DNS2Go customer you are trying to reach is currently offline.
Gruesse,
CK
Hi!
Oh, *ich* hab damit wenig Probleme.
woher kanem dann die anderen Dateien? Nichst das esmicht stört, würde mich nur interessieren! An Stelle des großen logos kam ein Text "gehört zu SELFHTML..."
daher habe ich das jetzt ein wenig abgeändert(die Adresse kennt aber eh niemand außer einer
Hand voll Leute hier)
http://selfarchiv.d2g.com/
Ist das so OK?
Kann ich dir nicht sagen, denn:
The DNS2Go customer you are trying to reach is currently offline.
Jetzt gehts wieder, war gerade offline.
Grüße
Andreas
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
Hallo nochmal!
War gerade über den 12 KB, habe das ein wenig verküzen müssen ;-)
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 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? Wenn ich bedenke das manche Suchworte nur ien einigen wenigen Postings eines Threads vorlkommen müßte das doch eigentlich besser gehen oder?
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.
Aber da bräuchte ich dann mehrmals match against, oder mysql 4
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?
Klar, aber die Leute wissen oft leider nicht die speziellen Wörter wonach sie sollten
Implementiere AND und NOT kompatibel zur bisherigen
Suche, und mach dann Deine Zeitmessungen nochmal.
Ok, ich versuche es mal. Ich lass die Suche jetzt wieder so wie sie ist und verwende eine testseite.
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!
Ja, das ist so wenn man nur den Fulltest verwendet, aber wenn man echte Where spalte = $wert dazuschreibt, wie ist das dann? So wie ich das jetzt messe ist das recht egal, auch ohen extra Index, der ja eh nichts bringen würde!
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. Die kann dann mitr einkompiliert werden, doer noch besser - direkt aus allen Postings gelöscht werden. Eine Dolppelte Datenhaltung sollte hier besser sein, der Performancxe zuliebe!
Kannst Du auch nicht, weil er nicht verwendet wird
(EXPLAIN!). Der macht nur das INSERT langsamer.
Substring-Funktionen arbeitet nicht mit Indexen.
ist trotzdem nicht viel langsamer als eine direkter Vergleich! Nachträglich geht sowas ja nicht - wie? Dann müßte ich alle Auswählen und dann nochmal manuel filtern, das ist doch bestimmt nicht gut!
Mach weiter - als nächstes sind die guten Erfahrungen
dran. ;-)
ich hoffe ;-)
Du hast zu große Treffermengen.
AND und LIMIT werden beide sehr viel bringen.
Limit 100 hatt ich immer drin, da ich mir dessen bewußt war, AND werde ich mal probieren!
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.
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!
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? Weiß imme rnoch nicht, ob ich jetzt einen Index pro Spalte anlegen soll oder einen über alle Spalten. 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.
Alles außer FULLTEXT ist momentan sinnlos. Im Augen-
blick sind Deine SQL-Stamements wichtiger, und das,
was die Datenbank daraus macht (EXPLAIN anwenden).
Aber was bringt mir EPPLAIN denn jetz wirklich? Es sagt ob es Fulltext verwendet, und sonst? Ist doch recht mager, oder? Ich zeige under http://selfarchiv.d2g.com/ oben das Statement an, und unter den Ergebnissen explain dazu.
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.
Aber nicht wenn zur Zeit wo ich und andere da getestet haben dieser index nich erstellt wird, das macht die DB ziemlich langsam! Wie gesagt, 80 Sekunden...
"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.
Nein, 1. ist das gut schnell wie ich finde, 2. zeigt EXPLAIN fulltext an
Laß die Finger von Substring-Operationen -
vorerst jedenfalls. Wenn Du _das_ filtern willst, tue
es in PHP - da geht es schneller.
Eben nicht!!! Ich will z,B. bei der Eijgabe 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.
Wenn ich das in PHP filtern wollte, müßte ich _ALLE_ Datensätze auswählen, in denen der Suchbegriff vorkommt, und dann in PHP filtern. Damit hat doch MySQL erheblich mehr Arbeit! Aber genau solche Sachen, da bin ich halt nicht so sicher! Aber probiere es mal aus, das ist gar nicht so langsam, ich hhätte da auch gedacht, aber folgende Abfrage dauert nur 0.02 Sekunden:
http://selfarchiv.d2g.com/index.php?suchausdruck=fsockopen&Kategorie=&Verfasser=Andreas&Listing=ranking&submit=Suche+starten
mit order by time dauerrt das ganze doppelt so lange.
So langsam funktioniert es auch, ich bekomme immer dieselben Ergebnis-Zeiten, also kann ich jetzt mal ein wenig testen, und werde die Tabelle vorerst nicht verändern.
Mal ein paar Messungen:
Standard Fulltext-Abfrage: 0.004
mit ORDER BY time: 0.007
mit 2. Bedingung (=) 0.004
mit 2. Bed. und ODER BY 0.005
mit INSTR 0.004
mit INSTR und ODER BY 0.006
mit 2. Bed und INSTR 0.005
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 ;-)
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 ;-)
Vielen Dank nochmal für die große Hilfe, ist jedesmal spannend Deine Postings zu lesen!
Viele Grüße
Andreas
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
Hi Andreas,
PS: Die Performance ist wirklch gut, habe oft Zeiten
erheblich unter 0,1 Sekunde(zugriffszeit auf die DB),
Achtung: Diese Zeitangabe ist sehr irreführend!
Dein PHP-Prozeß mißt nur die Zeit, die _er_ verbraucht,
nicht aber diejenige, die von der mySQL-Datenbank benö-
tigt werden! Dein PHP-Interpreter ist also schnell - mehr
siehst Du dadurch nicht.
Protokolliere Deine SQL-Statements, logge Dich per Shell
in mySQL ein, führe Deine Statements manuell aus und lies
_deren_ Zeitmessung. Das bringt Dich weiter.
Viele Grüße
Michael
ich habe gerade ziemlichen Quatsch geschreiben, von wegen Suchzeiten! Was ich nicht gemerkt hatte, die Suche bringt 0 ergebnise zurück!
Mit merh Ergebnissen sieht sieht das Ganze schon ganz anders aus, das erste mal dauert es 20 Sekunen, das 2,. mal 8, das 3. mal 3 dann 0,07, da bleibt es dann.
Wenn ich mein inste dabei nehme verdoppelt soch die Zeit auf 0,12, wenn ich die andere Bedingung mit "=" dazu nehme erhöht ich das ganze auf 0,1 Sekunden. Wenn ich beide verwende liegt es bei 0,11
Order by wirkt sich kaum aus, nur wenn auf andere Wehre-Bedingungen verzicjtet wird wird es nicht schneller.
Achtung: Diese Zeitangabe ist sehr irreführend!
warum? Ich mache das so:
$time_start = getmicrotime();
$result = mysql_query($query_string);
$time_end = getmicrotime();
$time = $time_end - $time_start;
echo "Dauer: ".$time." sec";
}
Und die Zeiten stimmen 100%ig mit der von MYSQL überein!(getestet)
BTW:
Wo genau stehen die Infos zum Forum? Halt welches Feld wie lang...? Ich kenn zwar das sourcefourge Projekt, aber wo steht das? Ändert sich da was beim cforum?
Grüße
Andreas
Hi Andreas,
Achtung: Diese Zeitangabe ist sehr irreführend!
warum? Ich mache das so:
$time_start = getmicrotime();
Aha - ist das Realzeit? (Ich nix PHP.)
Ich habe bei Perl CPU-Zeit gemessen und dann das be-
schriebene Problem erlebt. (Ich wollte insbesondere
sehen, wie die Anteile von system- und user time sind,
also an welcher Stelle ich drehen müßte, um den großen
Brocken weg zu bekommen.)
Bei mir ist die Perl-Laufzeit auch nur ein Bruchteil
einer Sekunde, die mySQL-Laufzeit streut aber erheb-
lich, zwischen Bruchteilen von und einigen Dutzend
Sekunden. Es gibt auch sehr unerwünschte Abfragen.
Und die Zeiten stimmen 100%ig mit der von MYSQL
überein!(getestet)
Fein.
Wo genau stehen die Infos zum Forum?
Halt welches Feld wie lang...?
Ich kenn zwar das sourcefourge Projekt, aber wo
steht das?
Gefühlsmäßig würde ich nach einer DTD für die XML-
Strukturen suchen.
Ändert sich da was beim cforum?
Da dieses kompatibel zum bisherigen Format sein soll,
vermutlich erst mal nicht.
Viele Grüße
Michael
Hi andreas,
Du hast sicher in der Doku gelesen, dass es
schneller geht, die Tabelle zunächst ohne
Volltext-Index anzulegen und zu befüllen, und
den Index erst nachträglich hinzuzufügen, oder?
Muß ich überlsen oder vergessen haben, jedenfalls
bin ich dann auch selbst auf den trichter gekommen,
nachdem bei Datensatz 4000 das ganze mehr als 1
Sekunde pro Datensatz dauerte - mit sinkender
Tendenz ;-)
Dann ist Deine Maschine offenbar doch ziemlich langsam.
Meine Erfahrungen stammen allerdings von einem SUN-
Server mit 4 GB RAM und mehreren CPUs ... der schlägt
sich bei dieser Aufgabenstellung großartig.
Aber auch das nachträgliche erstellen dauer bei
12.000 Datensätzen und ca. 50 MB mehr als eine Halbe
Stunde, das Nadelöhr ist ganz klar mein RAM, 256 ist
deutlich zu wenig.
Wieviel RAM hast Du mySQL zugeordnet? 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.
Und die 2. Sache ist das ich für Linux meien uralte
4GB Festplatte verwende, vermutlich mit tierischen
Ansprechzeiten, Drehzahl und mit 66er FSB...,
ausßerdem Rattert die so, muß glaube ich mal
tauschen :) Wobei Linux rtrotzdemnoch erheblich
schneller ist als Windows2K!
Hast Du /ver/tmp auf einer RAM-Disk liegen?
Hast Du mal mit iostat gemessen, ob Du während eines
lesenden Zugriffs auf den FULLTEXT-Index Schreibzu-
griffe (!) auf eine Festplatte hast?
Sehr gute Idee. Sollte man denn nicht lieber die
Indices zusammenlegem, ich meine jetzt im
allgemeinen, oder lieber enzelnde?
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.
Aber warum braucht der themenbereich keien Volltxt-
index?
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).
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.
Ich denke hier könnte man doch was draus machen,
natütlich nicht mit den Standards von mySQL 3.23,
aber so allgemein!
mySQL 4.0 kündigt mir nichts an, was die Funktionalität
oder Architektur Deiner Suche signifikant ändern würde.
Bedenke auch, dass du bei einer Abfrage über den
Volltextindex eine Relevanzangabe erhälst, die du
nutzen kannst ...
Ja, das ist wirklich gut. Nur was mich stört, die
kleinen Beiträge, mit wenig drin stehen ganz oben,
das ist IMHO falsch!
Lies mal im mySQL-Handbuch nach, wie diese Relevanz
berechnet wird.
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.
Man bräuchte noch ein Feld mit der Länge des
Threads. Vielleicht noch verknüpüft mit der
Vielosterstatistik, um mit einem Allgorythmus ein
kleines Ranking hinzubekommen, warum eigentlich
nicht?
Schreib Dir ein Konzept dafür. Ignoriere völlig, wie Du
es implementieren müßtest.
Definiere eine "gute" Ranking-Funktion. Wie man diese
dann umsetzt, soll Dich vorerst nicht interessieren.
Aber mydql hat doch auch eine statische Liste, udn
die iszt englische. Ich meine nur hierfür als
Pendant!
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.
Wobei ich gestehen muß, Ihr hattet Recht,
so viel schneller ist die DB auch nicht,
Gib nicht so schnell auf. Deine Lösung wird andere (!)
Stärken oder Schwächen haben.
aber auf der anderen Seite habe ich keine
Ahnung wie man das ganze wirklich performant
macht, da gibt es ja glaube ich noch einige
Möglichkeiten...
Poste doch mal die exakten SQL-Statements. Und schalte
die Verwendung der impliziten Rating-Funktion ab - die
kostet nämlich viel Zeit! Und gib die Treffer erst mal
unsortiert aus - sortieren kostet entsetzlich viel Zeit
bei vielen Treffern.
Aha! :) Wie du siehst, ist auch eine Datenbank-
lösung nicht endlos überlegen - mehr Performance
kriegt man also nur über schnellere oder
parallele Maschinen.
Sven, dem stimme ich nicht zu. Der Haupteffekt der
Datenbank ist die Verwendung einer logarithmischen
statt einer linearen Suche - das bringt bei den vor-
liegenden Daten wahrscheinlich mindestens eine Zehner-
potenz.
Wobei es IMO etwas Overkill ist, nur für die
Archivsuche eine eigene Maschine hinzustellen,
die dann auch noch regelmäßig die neuen
Archiveinträge mitgeteilt bekommen muß.
Google zieht sich da relativ leicht aus der
Affäre, weil dort in regelmäßigen Abständen
Updates der Suchdatenbank auf die Cluster
verteilt werden. Die Zeitabstände sind aber
wohl monatlich - für die Archivsuche unzumutbar!
Inkrementelles Indexing ist nicht das Problem.
Da gibt es durchaus noch ein paar Tricks.
Beispielsweise: Halte eine _zweite_ Datenbank im Hin-
tergrund, welche dieselben Postings enthält, und baue
für _diese_ den Index täglich neu, in einer via 'nice'
niedrig gescheduleten shell. Während dieses Aufbaus -
der via cron in den frühen Morgenstunden läuft - kann
die andere Datenbank online verfügbar sein.
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.
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.
mySQL 3.23 ist toll, wenn man gute Hardware verwendet.
was ich merke, wenn ich neue Wörter suche, dauert
das meist um 1 Sekunde. Wenn das Wort schonmal
gesucht wurde wird es _erheblich_ schneller.
Richtig - weil auf Teile des FULLTEXT-Baumes zugegrif-
fen wird, die beim zweiten Mal noch in irgend einem
Cache liegen.
So geht das immer weiter(nicht unendlich), aber das
ist genau das Gegenteil zu aktuellen Suche. Die
funktioniert umso besser, je wenger Leute sie
benutzen.
Das ist bei Deiner Suche genauso. Der Cache ist ja
irgendwann auch mal voll.
Bei der logarithmischen Suche und den Indices ist
das was anders, die DB merkt sich jede Suche!
"Jede" nicht.
Ich bin fest davon überzugt das sich das bei höherer
Belastung sehr positiv auswirkt!
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.
Viele Grüße
Michael
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:
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:
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
Hi Andreas,
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!
klar. Der reine Importer muß ja praktisch nicht denken
Meine Erfahrungen stammen allerdings von einem SUN-Server mit 4 GB RAM und mehreren CPUs ... Ja, das ist kein Wunder! Ich habe eien AthlonXP 2000 und 256 MB DRR RAM, da sollte ich bei gelegenheit
Deine CPU ist immerhin viermal schneller getaktet als meine ...
bdb_cache_size 8388600
Den BDB-Treiber benutzt Du nicht - das kannst Du vermutlich auf 0 setzen.
myisam_sort_buffer_size 8388608
Wenn ich mich recht erinnere, dann ist das hier der Kandidat für die CREATE INDEX-Statements. Wenn Du zuerst importieren und dann indexen willst, dann gib hier alles, was Du kannst.
War das alles oder gibts da noch interessante Dinge?
Hm, das ist lange her, daß ich diese Liste mal durch- gearbeitet habe - und alles habe ich damals auch nicht 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
Ja. Bei den Tabellen sieht es schon sehr gut aus, finde ich. Die mySQL-Tuning-Parameter kenne ich nicht gut genug, das macht ein Kollege von mir im Büro ...
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,
Haben wir verschiedene mySQL-Implementierungen? Zu jeder Tabelle gibt es drei Dateien:
und die Tabelle hat jetzt schon über 100 MB, dazu kommt ein 60MB Index, nur Fulltext und Primary.
Aha. Schaffst Du es, den Sortier-Puffer auf mehr als diese 60 MB aufzublasen? Dann ist zuerst INSERT und danach CREATE INDEX ziemlich schnell. Andernfalls ertrinkst Du bei dieser Methode in Disk-I/O.
Hast Du /ver/tmp auf einer RAM-Disk liegen? Du meinst /var/tmp?
Ups - das war aus dem Gedächtnis zitiert und sollte wohl eher /var/log heißen - kann bei Dir aber anders konfiguriert sein. In meinem Falle war es so, daß ich temporäre Objekte angelegt habe und mySQL die in dieses Verzeichnis geschrieben hat - in der sicheren Erwartung, dort eine RAM-Disk vorzufinden ... was bei uns aber nicht der Fall war ...
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 Zugriff- zeiten unter 8 ms,das wäre hier glaube ich ange- bracht
Ich weiß nicht, was Du investieren kannst.
Aber RAM ist für eine so spezielle hochperformante Anwendung praktisch durch nichts zu ersetzen - auch nicht durch eine teure Festplatte. 512 MB RAM kosten für einen modernen Bus so um die 150 Euro ...
Wer oder was ist "iostat"? Kenne ich nicht und es ist nichts mit dem Namen installiert.
Gnlpfts. Wieso ist UNIX eigentlich nicht gleich UNIX? (Bei mir gibt es dieses Kommando sowohl unter AIX als auch unter Solaris.)
Außerdem sind die lesenden Zugriffe sehr schnell, da kann ich kaum gleichzeitig schreiben und das noch messen... wie geht das?
iostat ist ein Systemkommando, welches die Zugriffe auf alle Devices periodisch auflistet. Ich habe bei Performancetests eine Shell offen, wo ich damit zu- sehe, was ich an Last auf das System werfe.
"top" ist ein vergleichbares, aber anderes Tool, das eher die CPU-Last beschreibt, aber beispielsweise auch die IOWAIT-Quote anzeigt.
Das ist halt komisch, ich kann da überhaupt gar keinen roten Faden finden. Mal dauert das 0,03 und mal 13.
Das kommt darauf an, ob Du auf den RAM oder auf eine Festplatte zugreifst. ;-)
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?
FULLTEXT generiert eine Menge von Zeilen-IDs in irgend einem Puffer - im Index steht ja nur eine Referenz auf die eigentliche Tabellenzeile drin. Jeder dieser Treffer muß nun dazu genutzt werden, die entsprechenden Felder aus der eigentlichen Tabelle zu fischen - je mehr Spalten, um so mehr Daten sind zu holen. Benötigt werden dabei alle Felder, die in der SELECT-Liste oder in einer WHERE-Klausel auftauchen. Anschließend werden die restlichen WHERE-Klauseln gegen diese Felder ausgewertet - deren Größe ist also durch- aus wichtig (ein LIKE %term% gegen die komplette Po- sting ist hier teuer, deshalb muß die Treffermenge hinreichend klein sein).
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.
Miß mit "top" oder irgendwas in der Art die IOWAIT- Quote während Deiner Abfragen. Besitzt Du mehrere Festplatten? Wenn ja: Kannst Du die Daten- und die Index-Datei Deiner Tabelle auf verschiedene Festplatten legen (per symbolic link)? In diesem Falle würdest Du verhindern, daß bei einem umfangreichen Zugriff auf sowohl Daten als auch Index- blöcke der Lesekopf der Festplatte ständig hin- und her positionieren muß ... das würdest Du dann an einer hohen IOWAIT-Rate erkennen können. Deine CPU ist sehr schnell - die sollte nicht von Deiner Platte ausgebremst werden.
btw, kennst Du einen Befehl der einem anzeigt wieviel Platz noch auf einer Platte/Partition zur Verfügung steht, möglichst in Byte?
"df -k" ?
Und man verwendest immer nur einen Index? Man könnte denselben Index mit mehreren Wörtern ja auch mehrmals abfragen
Ich vermute, das macht mySQL auch, wenn Du ein AND über mehrere MATCHes desselben FULLTEXT-Index machst. (Das müßte Dir EXPLAIN dann eigentlich auch so zeigen.)
$query = SELECT... WHERE"; foreach(explode("+",$suchstring) as $suchwort){ $query .= " match... against($suchwort)"; } mysql_query($query); So in etwa, was sagst Du dazu?
Entscheidend ist, was EXPLAIN dazu sagt. ;-)
- 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 Informa- tion für ein Ranking nutzen???
Verfeinere auf separate Vielposterstatistiken pro Kategorie. Meine "Expertise" für SERVER gegenüber JAVASCRIPT unterscheidet sich um Zehnerpotenzen. ;-)
- höhere Gewichtung des Titels
Ja, gefällt mir. Hat aber den Nachteil, daß es vom Suchbegriff abhängt, also zur Laufzeit berechnet werden muß. Die Vielposter-Kennzahl kann zur Import- zeit berechnet werden, und Du kannst die Ergebnisse direkt per ORDER BY danach sortieren!
- Noch höhere gewichtung der Kategorie
Unwahrscheinlich, daß das jemals etwas bewirkt.
- Vorkommen im Autoren-Feld
Da würde mir die in der bisherigen Suche vorhandene Möglichkeit, einzelne Terme gezielt nur in einzelnen Feldern zu suchen, besser gefallen. Ich will früher projezieren, um später weniger sortieren zu müssen.
- Die Zeit, neuere Threads ein wenig besser bewerten
Ack.
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!
Das ist implizit eine weitere WHERE-Klausel über den Author - erfordert aber, daß das Formular weiß, wer mit "ich" gemeint ist. (Login?)
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!
Wenn Dein Limit zuschlägt, dann ist ohnehin schon etwas schief gegangen: Dann hast Du vielleicht schon die be- sten Treffer ignoriert.
und was da noch so stand. Konnte man hier nicht auch irgendwo den Minimum-Wert für Suchwörter von 4 verändern?
"Diese Eigenschaft des FULLTEXT-Index der myISAM-Tabel- len von mySQL wird durch die Konstante MIN_WORD_LEN in der Datei myisam/ftdefs.h der mySQL-Quelltext-Distri- bution festgelegt."
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"!
Deshalb mußt Du den Anwender zwingen, so lange weitere Begriffe anzugeben, bis Du alle Treffer hinreichend schnell berechnen kannst.
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"!
Doch, kannst Du. ;-)
Wenn Du ein gutes Konzept für die Aufgabenstellung hast, mit Prioritäten für die einzelnen Anforderungen, dann kannst Du damit zu einem Spezialisten gehen, der an jede Deiner Anforderungen einen Haken machen, sie durchstreichen oder Dir die Kosten der Implementierung erklären kann. Denn die Art der Implementierung ist eben nicht die Aufgabe der Spezifikation. Umgekehrt kann Dir dieser Spezialist aber nicht Deine Aufgabenstellung schreiben, weil es Deine Aufgaben- stellung ist - eine sehr subjektive Angelegenheit also.
Definiere eine "gute" Ranking-Funktion. Wie man diese dann umsetzt, soll Dich vorerst nicht interessieren. Wenn ich das alleine mache schon ;-)
Beim Schreiben Deiner Aufgabenstellung kann ich nicht mithelfen - beim Umsetzen schon, wie Du siehst.
Das weiß ich auch nicht. Wäre es eigentlich nicht viel schlauer, diese Worte anstat mit einem Stop- Word-Liste zu filtern, diese zu entfernen?
Dann findest Du sie auch in Phrasen nicht mehr ...
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?
Nein, fürchte ich. Was weg ist, ist weg.
Du siehst, das ist ein trade-off. Aufgabe Deiner Spezifikation ist es, Dich zu entschei- den, was von beidem Dir wie wichtig ist - ob und wie es vereinbar ist, das entscheidet die Implementierung.
Aber das schlimmste ist die Beschränkung auf Worte über 3 Buchstaben!
Siehe oben: Eine Zeile ändern und mySQL neu übersetzen.
Die Relevanz wid doch immer ausgerechnet, wie soll ich das abschalten?
Ich dachte, die Relevanz wird nur dann ausgerechnet, wenn Du die Bewertungsfunktion in der SELECT-Liste hast. In diesem Fall wird dann auch implizit nach diesem Feld sortiert, selbst wenn Du kein ORDER BY angegeben hast.
Was meinst Du mit "stub file"? Eine Datei in die Du den Status schreibst, welche DB gerade verwendet wird?
Eine Datei, deren Name diesen Status ausdrückt.
Ich will sie gar nicht öffnen müssen (und das Betriebs- system erst mal die Berechtigung dafür prüfen lassen)
Wie kann ich denn den Cache so groß wie möglich bekommen?
Über die mySQL-Konfigurationsdirektiven.
Und wie kann ich das objektiv testen ...
Durch wechselnde Suchbegriffe - und zwischendurch ei- nen Neustart des mySQL-Daemons, wenn Dir die Beispiele ausgehen.
Viele Grüße Michael
Hi Andreas,
also erst mal vorweg:
1. Das, was Du machst, _ist_ vernünftig.
2. Wirklich gut wird die Suche aber nur, wenn Du mehr
als einen Suchbegriff erlaubst.
Daß die Ranking-Funktion von mySQL nicht zur
Aufgabenstellung paßt, hast Du ja selbst gesehen.
Ja, da hatten wir schonmal drüber diskutiert, aber
soweit ich weiß ist es im Selfforum nicht möglich
eigene <> in den HTML-Quellcode zu bekommen, oder?
Also sollte es gehen, oder? Irgendwie muß ich den
Code ja rausbekommen! Daher filtere ich erst die
Basisdaten aus dem Thread(Thema, User, zeit), dann
entferne ich die html-tags, und dannach wandele ich
html-entitäten um.
Wenn Du einen eigenen Indexer schreiben willst, dann
brauchst Du so etwas, ja.
Alternative: Laß Dir von Christian die existierenden
Indexdateien geben, damit Du erst mal die Datenbank
schnell kriegst.
Den Parser kannst Du hinterher immer noch schreiben.
Ich habe jetzt 3 Stunden lang versucht MySQL 4 zu
installiern, was an sich nicht schwer war,
Dein Modell funktioniert mit mySQL 3.23 gut genug.
Mach es erst mal damit.
denn gerade für Volltext-Suche ist die 4er erheblich
besser.
Hast Du die 4.0 schon mal damit im Einsatz gesehen?
(Ich noch nicht, ich kenne nur die Handbücher dazu.)
Was ich gemerkt habe, der Index muß immer aktuell
sein, wenn ich ein paar 1000 Datensätze in die
Tabelle schreibe, wird die Suche erheblich
langsamer.
Dann stimmt etwas nicht. Der Trick der Indexe ist doch
gerade, daß es _nicht_ langsamer wird.
Wenn Du 10000 Worte in einem binären Baum darstellst,
dann hat der eine Höhe von 13 Knoten. Eine Million
Worte bewirken eine Höhe von 20 Knoten - die Suche darf
also maximal um 50% mehr Zeit benötigen, tatsächlich
aber deutlich weniger, weil der gesamte Overhead (z.B.
das Parsen des SQL-Statements) unverändert anfällt.
Ich habe jetzt ca. 12.000 Datensätze in der DB(1 pro
Thread), und da dauert es mehr als 15 Minuten den
Index neu zu erstellen! Auch wenn ich eine kom-
pletten Dump im batch-modus einlese!
Das ist wahr.
Aber dieser Aufwand darf nur ein einziges Mal anfallen.
Und die ganze Zeit ist die CPU und der Arbeits-
speicher bis zum Anschlag ausgelastet!
Natürlich. Index bauen bedeutet Sortieren, und das
kostet sowohl sehr viel CPU-Last als auch sehr viel
RAM, um möglichst wenige I/O zu benötigen, die ja viel
langsamer wäre als Zugriffe im Hauptspeicher.
Ich denke daher das mehr CPU-Power und vor allem RAM
sehr wohl was bringt! Kann man nie genug haben,
zumindest solange das System drauf ausgereichtet
ist.
Ja - das Aufbauen eines großen Index kann Ressourcen
jeder Art brauchen. Also sollte man vermeiden, dies
zu oft zu tun.
Wie pflegt Ihr denn solche Indices?
Inkrementell. Auch wenn es langsam ist (siehe unten),
es ist in Deinem Fall die einzige Möglichkeit, wenn
die Postings online in Deine Datenbank fließen (das
wird ja am Ende der Entwicklung der Fall sein).
Ich habe eine solche Datenbank mit einer Million (!)
'Postings' drin (mittlere Größe: 2KB), und das inkre-
mentelle Indexen kostet so gut wie keine CPU-Zeit.
Die Datenbank lasse ich jetzt auch mal online, würde
mich mal interssieren was Ihr davon haltet.
Die Idee ist richtig, und Du wirst dabei wertvolle
Erfahrungen sammeln, die Du mit Daniela austauschen kannst.
id smallint(6) NOT NULL default '0',
Ich würde lieber 24 Bit nehmen als 6 Ziffern.
topic varchar(20) NOT NULL default '',
title varchar(100) NOT NULL default '',
Bei beiden kann Dir die Forum-Software die exakten
Maximalwerte sagen.
body text NOT NULL,
Wie lang ist "text"?
Gäbe es etwas Kleineres, das 12 kB aufnehmen kann?
time int(10) NOT NULL default '0',
Gute Idee - ich mag das, auch wenn mySQL dafür wahr-
scheinlich proprietäre Datentypen hat.
PRIMARY KEY (id),
UNIQUE KEY id (id),
Die untere Zeile ist redundant.
FULLTEXT KEY body (body,topic,title)
Wie ist es mit den anderen Spalten (author)?
) TYPE=MyISAM;
Yep. (Das ist der Defaultwert bei mySQL.)
Wobei ich glaube ich auf unique und Primärschlüsel
verzichten kann, denn das bringt hier eh nichts.
Kommt darauf an. Den Primärschlüssel für die ID würde
ich auch haben wollen - und sei es nur, um die Konsi-
stenz der Daten zu gewährleisten.
Meine 'Suche' kann beispielsweise nicht nur suchen,
sondern auch filtern - etwa die letzten 100 Postings
eines Autors etc. Dafür würdest Du dann den FULLTEXT-
Index nicht nehmen, sondern einen Index über die
Author-Spalte concat den timestamp.
Verschiedene Anfragearten können zu unterschiedlichen
Indexstrukturen führen, die parallel sinnvoll sind.
Die Gewichtung ist aber nicht das gelbe vom Ei.
Das ist noch viel zu unflexibel.
Vergiß die Ranking-Funktion. Bestimme erst mal einen
schnellen Zugriff auf alle legalen Treffer für
a) mehr als einen Suchbegriff und
b) Phrasen
Danach kannt Du immer noch eine eigene Ranking-Funk-
tion auf die gefundenen Treffer anwenden, wenn es denn
sein muß. Eine Ausgabe, die umgekehrt nach Datum sor-
tiert herausgespult wird wie bisher, ist auch nicht so
schlecht als erste Version. Wenn Deine Anwender mehrere
Suchbegriffe eingeben dürfen, die Du mit AND verknüpfen
kannst, wird die Treffermenge so klein, daß Du eine
gute Ranking-Funktion darauf anwenden kannst.
Der Phrasenfilter wird etwas schwieriger ...
entweder ich füge eine weiter Spalte ein, und hier
dann duch Leerzeichen getrennt 5 mal das Thema und
10 mal den Titel, und das dann mit in den Index
aufnehmen, oder 15 weiter Spalten mit entsprechend
5 mal Titel und 10 mal Themenbereich.
Mach's nicht.
Ruiniere Dir nicht Deinen Architekturansatz, bevor Du
diesen bezüglich Performance richtig beherrschst.
Ich habe auch schon ein eine eigene stop-word Liste
gedacht, indem ich beim Anlegen der Datensäzte dort
ausgewiesene Wörter entferne.
Schau im Archiv nach - ich habe schon mal gepostet,
wo im mySQL-Quelltext dessen eigene Stopwortliste
steht und wie Du diese anpassen kannst.
Wobei ich gestehen muß, Ihr hattet Recht, so viel
schneller ist die DB auch nicht,
Momentan vergleichst Du Äpfel mir Birnen. Gib nicht so
schnell auf.
aber auf der anderen Seite habe ich keine Ahnung
wie man das ganze wirklich performant macht,
Schau Dir erst mal mit EXPLAIN an, wie die Datenbank
Deine Statements überhaupt umgesetzt hat.
Wird der FULLTEXT-Index wirklich verwendet?
Viele Grüße
Michael
Hi!
also erst mal vorweg:
- Das, was Du machst, _ist_ vernünftig.
schön zu hören :)
- Wirklich gut wird die Suche aber nur, wenn Du mehr
als einen Suchbegriff erlaubst.
mache ich doch !? Du kannst eingeben was Du willst, MySQL zerteilt des String selbst udn sucht nach dn einzeknen Wörtern. Das dumme ist nur, es müssen nicht alle Wärter gefunden werden, du das macht das ganez natürlich abhängig von der Qualität des Rankings, und das ist das Problem!
Daß die Ranking-Funktion von mySQL nicht zur
Aufgabenstellung paßt, hast Du ja selbst gesehen.
ja
Alternative: Laß Dir von Christian die existierenden
Indexdateien geben, damit Du erst mal die Datenbank
schnell kriegst.
Den Parser kannst Du hinterher immer noch schreiben.
Naja, jetzt habe ich das komplette Archiv 2002, das reicht zum probieren aus, denke ich!
Ich habe jetzt 3 Stunden lang versucht MySQL 4 zu
installiern, was an sich nicht schwer war,
Dein Modell funktioniert mit mySQL 3.23 gut genug.
Mach es erst mal damit.
Ja mir bleibt eh nicht anderes übrigm da ich 4.0 einfach nicht mit PHP ans laufen bekomme. Vermutlch ginge es mit PERL, aber ich brauch die DB nicht nur für diese Suche, und überall anders verwende ich noch PHP.
Warum ich unbedingt 4 haben möchte hat folgende Gründe(Zitat):
* +wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile enthalten sein muss.
* -wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile nicht enthalten sein darf.
* < und > können benutzt werden, um die Wortgewichtung in der Anfrage herab- und heraufzusetzen.
* ~ kann benutzt werden, um einem 'Rausch-Wort' ein negatives Gewicht zuzuweisen.
* * ist ein Trunkierungsoperator.
Die Boole'sche Suche benutzt eine vereinfachte Art, die Relevanz zu berechnen, die keine 50%-Schwelle hat.
denn gerade für Volltext-Suche ist die 4er erheblich
besser.
Hast Du die 4.0 schon mal damit im Einsatz gesehen?
(Ich noch nicht, ich kenne nur die Handbücher dazu.)
Wieso sollte das nicht gehen? Unter Windows habe ich eien ganze Zeit mit 4.0 udn PHP gearbeitet, wobei die API hier noch einige Schwachstellen hatte, lag aber größtenteils an PHPmyAdmin und dem noch"experimentellen" Apache2 Support von PHP. Und meines Wissens soll 4.0 irgendwann Ende dieses Anfang nächsten Jahres Stable sein, dann sollte das funktionieren. Und wo wenn nicht bei sowas kann man beta-Versionen verwenden und von derartig großen Vorteile profitieren!
Dann stimmt etwas nicht. Der Trick der Indexe ist doch
gerade, daß es _nicht_ langsamer wird.
Das Problem ist, das andere Prozesse zur selben Zeit viel Last gekostet haben...
Die Datenbank lasse ich jetzt auch mal online, würde
mich mal interssieren was Ihr davon haltet.
Die Idee ist richtig, und Du wirst dabei wertvolle
Erfahrungen sammeln, die Du mit Daniela austauschen kannst.
sehr gerne! Wenn ich helfen kann, aber wie Du siehst kenn ich mich noch sehr wenig aus...
id smallint(6) NOT NULL default '0',
Ich würde lieber 24 Bit nehmen als 6 Ziffern.
und wie nehem ich das? In welchem Format kann ich das speichern? Udn wie muß ich dann schreiben?im Bits Konvertieren???
topic varchar(20) NOT NULL default '',
title varchar(100) NOT NULL default '',
Bei beiden kann Dir die Forum-Software die exakten
Maximalwerte sagen.
Stimmt. Ich würd egerne CHAR nehmen, aber das geht nicht, da Text ein Feld mit variable Länge ist.
body text NOT NULL,
Wie lang ist "text"?
Gäbe es etwas Kleineres, das 12 kB aufnehmen kann?
Text hat L+2 Bytes, wobei L < 2^16, sind max 64 kB
darunter gibt es nur noch TINYBLOB, TINYTEXT L+1 Bytes, wobei L < 2^8, aber das ist wohl etwas wenig!
time int(10) NOT NULL default '0',
Gute Idee - ich mag das, auch wenn mySQL dafür wahr-
scheinlich proprietäre Datentypen hat.
Ja, ich könnte das in eien Timestamp oder Datetima Spalte schreiben. Wobei das erheblich mehr Daten sind, die ich nicht wirklich brauche und die nur Performanc und Hauptspeicherplatz kosten!
FULLTEXT KEY body (body,topic,title)
Wie ist es mit den anderen Spalten (author)?
Naja, hast Recht.
) TYPE=MyISAM;
Yep. (Das ist der Defaultwert bei mySQL.)
und soll auch das schnellste sein, oder?
Die Gewichtung ist aber nicht das gelbe vom Ei.
Das ist noch viel zu unflexibel.
Vergiß die Ranking-Funktion. Bestimme erst mal einen
schnellen Zugriff auf alle legalen Treffer für
a) mehr als einen Suchbegriff und
Das funktioniert doch schon! ODer meinst Du Nur Datensätze, die _alle_ BEgriffe entahlten?
b) Phrasen
Das hat doch nur Sinn wenn der Index dieses unterstützt, und das machen IMHO weder Version 3 noch 4
Danach kannt Du immer noch eine eigene Ranking-Funk-
tion auf die gefundenen Treffer anwenden, wenn es denn
sein muß. Eine Ausgabe, die umgekehrt nach Datum sor-
tiert herausgespult wird wie bisher, ist auch nicht so
schlecht als erste Version. Wenn Deine Anwender mehrere
Suchbegriffe eingeben dürfen, die Du mit AND verknüpfen
kannst, wird die Treffermenge so klein, daß Du eine
gute Ranking-Funktion darauf anwenden kannst.
Stimmt, das hatte ich auch schon gedacht, das Ergebinis in einen Array schreiben und den munter sortieren!
Der Phrasenfilter wird etwas schwieriger ...
Wie soll das auch gehen? Das müßte man komplett anders implementieren, wobei, vielleicht gejt es ja mit meinem instr(), wobei das jeglicher Optimierung spotten würde!
Schau Dir erst mal mit EXPLAIN an, wie die Datenbank
Deine Statements überhaupt umgesetzt hat.
Wird der FULLTEXT-Index wirklich verwendet?
Jetzt kann man die Ausgabe von EXPLAIN und die Query selbst sehen! Das hilft Dir vielleicht das besser zu verstehen. Da sieht man nämöich, das ich im "standardmodus" mit "Rabking" gar nichts an einer originalen Fulltext-Query verändere. Vielleicht ist der begriff auch noch faslch gewählt, da kommt ja eh nur "Quatsch" zurück!
Danke vielmals für Deine ausführlichen Antworten! Zu den anderen schreibe ich später noch was.
Grüße
Andreas
PS: Das ist jetzt das 2. mal das ich mit Mozilla nicht mehr weiterkomme, da ließ sich einfach nichst aus der ZWischenablage in das Textfeld kopieren...
Hi Andreas,
- Wirklich gut wird die Suche aber nur, wenn Du mehr
als einen Suchbegriff erlaubst.
mache ich doch !? Du kannst eingeben was Du willst,
MySQL zerteilt des String selbst udn sucht nach dn
einzeknen Wörtern. Das dumme ist nur, es müssen
nicht alle Wärter gefunden werden, du das macht das
ganez natürlich abhängig von der Qualität des
Rankings, und das ist das Problem!
Eben. Deshalb ist diese Methode nicht so arg toll.
Ich parse die Eingabestrings selbst und generiere mir
daraus eine WHERE-Klausel, die pro Term ein AND mit
einem separaten FULLTEXT-MATCH enthält. Ich erzwinge,
daß alle Terme drin sein müssen. Und das ist selbst
mit mySQL 3.23 ziemlich schnell - und ich kriege sehr
kleine Treffermengen, wenn ich genügend Terme angebe.
Naja, jetzt habe ich das komplette Archiv 2002,
das reicht zum probieren aus, denke ich!
Ack.
Warum ich unbedingt 4 haben möchte hat folgende
Gründe(Zitat):
REPAIR TABLE mit FULLTEXT-Indexen, ALTER TABLE
mit FULLTEXT-Indexen und OPTIMIZE TABLE mit
FULLTEXT-Indexen läuft jetzt bis zu 100 mal
schneller.
Nichts davon brauchst Du im Normalbetrieb. REPAIR
brauchst Du hoffentlich nie, ALTER TABLE auch nicht,
sobald Deine Tabelle Suche fertig ist; OPTIMIZE auch
nur ein einziges Mal, wenn überhaupt (ich benutze das
gar nicht).
MATCH ... AGAINST wird folgende Boolesch
Operatoren unterstützen:
Ja, es wird besser. Aber das sind "nice to have"-
Funktionen, finde ich.
* +wort bedeutet, dass das Wort in jeder
zurückgegebenen Zeile enthalten sein muss.
* -wort bedeutet, dass das Wort in jeder
zurückgegebenen Zeile nicht enthalten sein darf.
Beides ist durch entsprechend generierte WHERE-
Klauseln schon jetzt möglich.
* < und > können benutzt werden, um die
Wortgewichtung in der Anfrage herab- und
heraufzusetzen.
Ja, aber ich will diese Ranking-Funktion ohnehin
nicht benutzen. Was ich an Deiner Stelle einbauen
würde, wäre eine eigene Ranking-Funktion. Ein Term
dieser Funktion wäre die Anzahl der Postings des
Autors in dieser Kategorie ... das hebt die Spezia-
listen heraus, das _muss_ eine gute Näherung sein.
* * ist ein Trunkierungsoperator.
Was heißt das genau?
Die Boole'sche Suche benutzt eine vereinfachte Art,
die Relevanz zu berechnen, die keine 50%-Schwelle
hat.
Relevanz interessiert mich im Moment überhaupt nicht.
Da traue ich meiner eigenen Kristallkugel mehr. ;-)
Suchen sind jetzt wegen optimierter
Suchalgorithmen bis zu 2 mal schneller.
Ja, das ist prima. Den Faktor 2 nehmen wie später mit,
wenn sich die Software installieren läßt.
Den Entwurf darauf aufzubauen, dafür ist es zu wenig.
Hast Du die 4.0 schon mal damit im Einsatz
gesehen? (Ich noch nicht, ich kenne nur die
Handbücher dazu.)
Wieso sollte das nicht gehen?
Habe ich das behauptet?
Das Produkt, für welches ich meine Suchmaschinen im
Büro schreibe, liefert eine 3.23-Datenbank mit aus -
mit der muß ich arbeiten, weil dort die Entitlement-
Daten drin stehen, gegen welche meine Suche ihre
Treffer filtern muß usw.
Und meines Wissens soll 4.0 irgendwann Ende dieses
Anfang nächsten Jahres Stable sein, dann sollte das
funktionieren.
Bis dann das Produkt unserer Schwesterfirma mit mySQL
4.0 läuft, wird es also Ende 2003. :-(
sehr gerne! Wenn ich helfen kann, aber wie Du
siehst kenn ich mich noch sehr wenig aus...
Du kannst auf jeden Fall mal eine Checkliste all
dessen machen, was die bisherige Suche kann, und Dir
rudimenär überlegen,
a) ob und wie es via mySQL implementierbar wäre und
b) wie wichtig das jeweilige Feature ist.
Kandidaten, die mir spontan Probleme bereiten würden,
sind:
1. Verwendung regulärer Perl-Ausdrücke in Termen.
(Das wird schwierig, aber vielleicht mit mySQL 4
möglich?)
2. case-sensitive Suche (finde ich wichtig).
3. Die Möglichkeit, Terme mit Suchbereichen einzugeben
(author:cheatah body:mailto).
Das ist machbar, erfordert aber eine viel genauerer
Analyse der eingegebenen Suchbegriffe - also: Arbeit.
id smallint(6) NOT NULL default '0',
Ich würde lieber 24 Bit nehmen als 6 Ziffern.
und wie nehem ich das? In welchem Format kann ich
das speichern? Udn wie muß ich dann schreiben?
im Bits Konvertieren???
Die genaue Notation habe ich nicht im Kopf - kannst
Du die (6) nicht einfach weglassen?
Ich meinte nur: smallint belegt doch wohl sowieso eine
bestimmte Anzahl bits - warum dann auf 6 Dezimalen
einschränken?
) TYPE=MyISAM;
Yep. (Das ist der Defaultwert bei mySQL.)
und soll auch das schnellste sein, oder?
Es ist der einzige, der FULLTEXT kann ... das ist eine
Erfindung des MYISAM-Tabellentreibers, nicht von mySQL.
a) mehr als einen Suchbegriff und
Das funktioniert doch schon! ODer meinst Du
Nur Datensätze, die _alle_ Begriffe enthalten?
Letzteres, ja.
Die Treffermenge _muß_ deutlich kleiner werden.
b) Phrasen
Das hat doch nur Sinn wenn der Index dieses
unterstützt, und das machen IMHO weder Version 3
noch 4
Eine Phrase läßt sich durchaus mit mySQL 3.23 lösen:
Zerschlage sie in all ihre 'Worte' (gemäß der Termi-
nologie von FULLTEXT), mache ein AND darüber, bete ein
bißchen, daß es _jetzt_ nur noch wenige Treffer sind,
und mache anschließend ein LIKE %phrase% über das
gesamte Posting!
Wenn Du die Treffermengen klein genug kriegst, wird
das funktionieren. Mit großen hast Du keine Chance.
(Deshalb ist mir das AND so unheimlich wichtig!)
gute Ranking-Funktion darauf anwenden kannst.
Stimmt, das hatte ich auch schon gedacht, das
Ergebinis in einen Array schreiben und den munter
sortieren!
Die Ranking-Funktion kann auch schon statisch beim
Import berechnet und in der Tabelle abgespeichert wer-
den. Stell Dir vor, diese Funktion wäre identisch
zur Anzahl der Postings des Autors in dieser Kategorie
zum Zeitpunkt der Aufnahme dieses Postings. Dann wäre
das einfach eine zusätzliche Spalte in Deiner Tabelle,
nach der Du die Treffer mit ORDER BY auslesen kannst.
Der Phrasenfilter wird etwas schwieriger ...
Wie soll das auch gehen?
Siehe oben.
Schau Dir erst mal mit EXPLAIN an, wie die
Datenbank Deine Statements überhaupt umgesetzt
hat.
Wird der FULLTEXT-Index wirklich verwendet?
Jetzt kann man die Ausgabe von EXPLAIN und die
Query selbst sehen!
Fein - das hilft allen Testern, zu sehen, was passiert.
Viele Grüße
Michael
Hallo Michael!
* +wort bedeutet, dass das Wort in jeder
zurückgegebenen Zeile enthalten sein muss.
* -wort bedeutet, dass das Wort in jeder
zurückgegebenen Zeile nicht enthalten sein darf.
Beides ist durch entsprechend generierte WHERE-
Klauseln schon jetzt möglich.
Aber da geht e mit einer Abfrage des index, das geht heute nicht!
* < und > können benutzt werden, um die
Wortgewichtung in der Anfrage herab- und
heraufzusetzen.
Ja, aber ich will diese Ranking-Funktion ohnehin
nicht benutzen. Was ich an Deiner Stelle einbauen
würde, wäre eine eigene Ranking-Funktion. Ein Term
dieser Funktion wäre die Anzahl der Postings des
Autors in dieser Kategorie ... das hebt die Spezia-
listen heraus, das _muss_ eine gute Näherung sein.
* * ist ein Trunkierungsoperator.
Was heißt das genau?
Wenn ich mich nicht irre sowas wie wildcard, um Substrings zu finden, oder?
MySQL 4 hat noch eine nete Funktion, und zwar:
"Funktionen wie SQL_CALC_FOUND_ROWS und FOUND_ROWS() ermöglichen herauszufinden, wie viele Zeilen eine Anfrage ohne eine LIMIT-Klausel zurückgegeben hätte."
Das ist wohl sehr Sinnvoll!
und in einer der nächten Versionen wird tatsächlich eine Phrasensuche implementiert.
- Verwendung regulärer Perl-Ausdrücke in Termen.
(Das wird schwierig, aber vielleicht mit mySQL 4
möglich?)
Das ist ja bereits möglich, ähnlich wie LIKE, aber ich denke das ist ziemlich langsam.
- case-sensitive Suche (finde ich wichtig).
wofür? bei welchem Wort würde es einen Unterschied machen ob Du es groß geschreiben oder klein geschreiben fimdest?
- Die Möglichkeit, Terme mit Suchbereichen einzugeben
(author:cheatah body:mailto).
Das ist machbar, erfordert aber eine viel genauerer
Analyse der eingegebenen Suchbegriffe - also: Arbeit.
Ja, das mache ich ja teilweise jetzt schon, nur auf mehrere Variablen verteilt, den Suchstring prüfe ich auf + und -
Wär lkein Problem, was ich vergessen habe ist mailto zu parsen ;-) Wäre ja nicht verkehrt das genaus zu machen wie die Vielposterstatistik, die ja auch auf den Email-Adressen beruht. Nochmal wegen Vielpposter-Satstistik, bzw. deren Verwendung fpr eun REanking, würdest Du jedesmal die Relevanz während der Suche aus der Posting-Tabelle abfragen, oder eher eine eigene Poster-Statistilk Tabelle zu verwenden, die dann per Cron oder bei Inserts aktualisiert wird!
Die genaue Notation habe ich nicht im Kopf - kannst
Du die (6) nicht einfach weglassen?
Ich glaube nicht. Aber das ist ein Verständnis-Problem meinerseits: Wie kann ich ein Feld auf Bits beschrängen, ud wie füge ich eine Zahl als Bit ein? Und was habe ich davon? Ich dachte interger wäre schon gut!
Ich meinte nur: smallint belegt doch wohl sowieso eine
bestimmte Anzahl bits - warum dann auf 6 Dezimalen
einschränken?
Ach so.
Eine Phrase läßt sich durchaus mit mySQL 3.23 lösen:
Zerschlage sie in all ihre 'Worte' (gemäß der Termi-
nologie von FULLTEXT), mache ein AND darüber, bete ein
bißchen, daß es _jetzt_ nur noch wenige Treffer sind,
und mache anschließend ein LIKE %phrase% über das
gesamte Posting!
Wenn Du die Treffermengen klein genug kriegst, wird
das funktionieren. Mit großen hast Du keine Chance.
(Deshalb ist mir das AND so unheimlich wichtig!)
Wenn ich nachträglch so eie Filrung vornehme, dann kann ich ja das Limit erhöhen, das weiß ich ja vorher, z.B. von 200 auf 1000. Sonst habe ich 200 Datensätze von denen aber nur 10 die Phrase enthalten, aber noch 50 oder mehr aufgrund des niedrigen Limits schon vorher unter den Tisch gefallen sind.
Stimmt, das hatte ich auch schon gedacht, das
Ergebinis in einen Array schreiben und den munter
sortieren!
Die Ranking-Funktion kann auch schon statisch beim
Import berechnet und in der Tabelle abgespeichert wer-
den. Stell Dir vor, diese Funktion wäre identisch
zur Anzahl der Postings des Autors in dieser Kategorie
zum Zeitpunkt der Aufnahme dieses Postings. Dann wäre
das einfach eine zusätzliche Spalte in Deiner Tabelle,
nach der Du die Treffer mit ORDER BY auslesen kannst.
Aber die Rankong-Funktion ist doch abhängig von der Suche, woher willst Du beim Import wissen was später mal gesucht wird? Sollte man das nicht vielleicht eher mit tenporären HEAP-Tabellen machen, in die man das Ergebnis schreibt und da die Relevanz berechnet?
Fein - das hilft allen Testern, zu sehen, was passiert.
Aber EXPLAIN gibt glaube ich viel zu wenig aus, stimmt das so? Sind halt 6 aAngaben oder so, mehr nicht. Was ich aber daraus groß ableiten soll, auißer das der Fulltext wohl jedesmal verwendet wird, weiß ich nicht.
Viele Grüße
Andreas
Hallo!
Eigentlich dachte ich hätte das gestern schon gepostet, hat wohl was nicht geklappt, also mochmal:
Habe die Suche jetzt erweitert, mit folgenden Zusatzfunktionen
neue Adresse: http://selfarchiv.knet-systems.de(da dyndns manchmal extrem langsam ist, und ich brauche nur HTTP, also habe ich auf dem Webserver eine HTTP-Weiterleitung per Rewrite-Modul eingreichtet)
mit "vollem Fultext-Cache", indem ich die Webalizer-Suchstatistik geparst und als SQL-SELECTs mit entsprechenden Gewichtungen(Wiederholungen) ausgeführt habe (http://webalizer.teamone.de/selfforum/usage_200210.htm#TOPSEARCH)
Wenn man genauso sucht wird es je nach Vorkommen der Suchbegriffe extrem schnell! Aber mit anderen Begriffen, oder mit zusätzlichen WHERE-Bedingungen wie Autor oder Kategorie wird es am Anfang imer noch langsam, da dies neu gesucht werden muß. Aber das sollte sich im Alltag auch einstellen.
Im Augenblick denke ich das das sehr performant funktionieren würde. Vor allem wenn man noch ein paar Parameter(Cache-Größen, Verwendung v. MySQL4) verbessert, aber da weiß ich nicht weiter.
Genauso habe ich keine Ahnung wie eine Phrasen-Suche performant funktionieren könnte.
Viele Grüße
Andreas
Hallo!
Ich habe jetzt nochmal einiges zu mysql-Server Parametern gelesen.
Einige Ideen:
Dann noch Parameter tunen:
Folgende Optionen sollte man vielleicht verändern:
Funktion | aktuelle Einstellung
--------------------------------+---------------------
key_buffer_size | 8388600
myisam_sort_buffer_size | 8388608
myisam_max_extra_sort_file_size | 256
myisam_max_sort_file_size | 2047
record_buffer | 131072
record_rnd_buffer | 131072
query_buffer_size | 0
sort_buffer | 2097144
table_cache | 64
So. Ich denke ich weiß zumindest bei den meisten Parametern was die bedeuten, aber ich abe natürlich 0 Ahnung wie ich die am besten einstelle.
Vielleicht kann ja jemand kurz sagen welche dieser Parameter in diesem Fall(Forum-suche), vielleicht verändert werden sollten, um die Performacne der Suche zu steigern.
ich würde jetz sagen alles so groß wie möglich, aber in der Doku steht z.B., wenn viele Anfragen kommen, sollte man die lieber erheblich verkleinern?!?!? Das versteh ich überhaupt nicht, was bringt mir ein key_buffer von 32K? Dann muß doch alles über die Platte, was erheblich langsamer ist.
Ich habe ja nur eine Tabelle, also brauch ich wohl keine großen Table cache, wobei die eine Tabelle über 100MB hat, und der Index dazu 60 MB. Könnte man nicht bedes einfach komplett in den Cache laden? Mit welchen Paramtern?
Eine Engstelle ist auch der Sortier-Puffer, denn gerade das macht die Suche ja so langsam, oder?
Hat es Sinn dafür andere, nicht verwendete buffer zu löschen, also für innodb....?
Frage zum Index, da steht das man bei einem Idex über mehrere Spalten die mit den meisten Dublikaten an den Anfang schreiben soll, wre hier also index(Kategorie, Autor, Titel, Text), sollte man das so machen? Weiß nämlich nicht ob das auch so für FULLTEXT gilt!
Viele Grüße
Andreas
PS: Bloß nicht denen das Ihr auf alle Fragen antworten sollt, bin über jeden keinsten Tipp sehr dankbar! Habe damit noch gar keine Erfahrung!
Nachtrag
;-)