Andreas Korthaus: stopword-list zum SELFForum

Beitrag lesen

Hallo!

Für eine Datenbank sollte das absolut kein Problem sein. Wichtig ist, dass das DB-Layout in sich stimmig ist - und dazu gehören Tabellenstruktur, Indizes etc. und auch die Statements.

Ja, nur ist das ja nicht die eigentliche Tabelle in der ich suche, die soll nur dazu dienen möglichst performante SQL-Statements zu generieren. Sicher ist das kein Problem, ich hatte zwischenzeitlich, mehr oder weniger aus Versehen mal eine Tabelle mit über 50 Mio Datensätzen und einigen GB Daten! Das ging auch noch erheblich besser als ich dachte!

Leider habe ich mit MySQL wenig Erfahrung und kann daher nicht abschätzen, wie und wie gut MATCH arbeitet bzw. wie es sich performanter gestalten lässt. Möglicherweise bringt ein Ersatz dieser Funktion Vorteile: Vorstellbar wäre z.B. eine Tabelle, die Wort auf Datensatz matcht (n:m), mit einem "simplen" Index. Wahrscheinlich ist ein Volltext-Index nichts anderes; aber vielleicht spart man sich damit den Overhead überflüssiger Funktionalität.

Ich denke nicht das ich das besser hinbekomme, da mysql das eigenlich schon recht performant macht. Vor allem wenn ein Suchbegriff mehrmals gesucht wird, ist das Statement im Cache und nach dem 3,. oder 4. mal dauert die Suche nur noch wenige 1/100 Sekunden. Das Problem bereiten mir seltenere Suchanfragen, die den größten Teil der Anfragen ausmachen. Und da ist es ganz entscheindend in welcher Reihenfolge gesucht wird, das kann durchaus um den Fakter 10 schneller werden wenn das seltene Wort vorne steht!

jedenfalls suche ich jetzt nach Mitteln und Wegen, sinnlose Daten aus der Tabelle rauszuschmeißen. Ich kann garantiert 95% guten Gewissens wegschmeißen, aber manuell mit 700.000 Datensätzen - unmöglich.

Warum? ORDER BY COUNT(*) DESC, und einfach von oben nach unten durchgehen. Dort werden die meisten relevanten Stopwords sein, und wenn's bei "kleineren" Mengen welche gibt, fallen die ohnehin weniger ins Gewicht. Alternativ kannst Du auch mal nach "stopwords list german" u.ä. googeln.

Order By über eine Tabelle mit 700.000 Datensätzen ist eine denkbar schlechte Idee! Erst muß man die Datensätze filtern und danach in einer temporären Tabelle sortieren.

Tja, Leerzeichen sind eben nicht unbedingt die besten Trenner... :-) Eine mögliche RegExp zur Ermittlung von Wörtern wäre z.B. "\b([a-z-]+)\b", wenn auch nicht zwingend die ideale.

Ja, das dachte ich auch, aber ich dachte dann auch, das kann ich ja auch hinterher auseinander-sortieren, vor allem da das Script schon so eine halbe Stunde gebraucht hat. So wie ich es gemacht habe geht es nicht mit regulären Ausdrücken, und dann würde es _erheblich_ langsamer. Ich will jetzt erstmal mit einigen RegExp ein paar Sachen löschen, halt alle Wörter mit 3 Zeichen und weniger, ale Wörter ohne Buchstaben, aber hiermit hätte ich dann nichtmal 5 % gelöscht. Es gibt einige Überschneidungen mit "", oder , oder groß-klein. Das und die Stopwords sollten nochmal was bringen, vielleicht 20%, aber das ist immer noch viel zu viel! Es ist einfach absolute Zeitverschwendung wenn die Tabelle größer ist als sie sein muß. Mir kommt es _ausschleißlich_ auf Performance an, daher mache ich das überhaupt, und nicht um mir noch eine Bremse oder ein Ranking einzubauen.

HTML- und anderen Code zu erkennen ist sicher eine Lebensaufgabe, um die ich Dich nicht wirklich beneide... andererseits ist es u.U. gerade ein Code, nach dem man sucht; frei nach dem Motto "Wie war das noch mit getElementById?".

Genau das ist es, wenn jemand sowas sucht ist die Suche enorm schnell. Und gerade darauf soll die Suche optimiert werden.

Du solltest Dir in erster Linie überliegen, wie Du "sinnlos" definieren möchtest, und was andere - besonders die Suchenden - wohl von dieser Definition halten werden.

Das habe ich, das Problem ist jetzt die sinnlosen Wörter zu entfernen, eine stopword-Liste ist wirklich nur ein Tropfen auf den heißen Stein.

Wenn die Datenbankabfragen zu lange dauern, dann drängt sich zuallererst eine Schlussfolgerung auf: Das DB-Layout ist suboptimal.

An dessen Optimierung arbeite ich ja gerade, also an der Tabellenstruktur kann ich nicht viel falsch machen, da es nur eine Tabelle ist, und einen vernünftigen Fulltext-Index habe ich ebenfalls. Und wie gesagt, mit gecachter Anfrage, alles prima, nur mit neuen Anfagen dauert es je nachdem bis zu 20 Sekunden. Dieselbe Anfrage nach dem 3. mal dauert z.B. 0,3 Sekunden. Mit einem gut sortierten String vielleicht 2-5 statt 20 Sekunden, je nach Suchbegriff.

Ist die Reihenfolge wirklich so von Bedeutung? Krass.

hätte ich auch nicht gedacht, das hat Michael Schröpl mir kürzlich erklärt, und es stimmt wirklich ;-)

Aber gab es bei MATCH nicht auch die Möglichkeit, mehrere Wörter in einem einzigen String anzugeben? An irgendsoetwas meine ich mich jedenfalls zu erinnern...

Das war meine erste Lösung, aber aus irgendeinem Grund ist das mit mehreren matches besser gewesen, aber das weiß ich gerade auch nicht mehr warum ;-)

Was ich bräuchte sind ein paar Reguläre Ausdrücke die mal so richtig in der Tabelle aufräumen, aber meine zaghaften Versuche bringen nie viel. Ich habe immer Angst wichtige Dinge zu löschen. Ich denke wenn ich hier einen performanten Zugriff auf diese Tabelle hinbekomme, dann muß ich nur noch gucken das ich mittels RAM Disk die kompletten Daten in den RAM bekomme, am besten die kompletten Tabellen und indices, dann noch den Anfragen-Cache schön hochsetzen dann sollte das schnell genug sein, hoffe ich ;-) Übrigens ist mein Fulltext-Index größer als die Daten selbst, mit 110:105 MB ;-)

Grüße
Andreas

PS: Habe de ganze Zeit schon Probleme mit dem Abschicken "serverseitieg Schwierigkeiten..."