Hallo Michael!
Ich habe das mit Der HEAP-Tabelle nur gemacht, um dei Daten irgendwie zum sortieren zwischenzu- speichern. Und das geht wirklich noch erheblich besser und schneller als ich gedacht hätte.
Das wundert mich.
Wieso? das Wesen einer HEAP-Tabelel ist es doch die Daten im RAM, zu speichern, das ist doch perfekt, und in der Doku steht doch auch das es ganeu dazu gedacht ist, also nicht ganz, aber so ähnlich ;-)
Anläßlich unserer Diskussion habe ich in meiner Anwendung vorgestern eine meiner temporären Tabellen auf HEAP umgestellt, und es war ein Desaster: Der Aufbau der sortierten Struktur dauerte schon bei einigen hundert Treffern entsetzlich lange (20 Sekun- den oder so).
Dir ist klar das ich die Temporäre Tabelle mit den den Ergebnissen der Fulltext-Suche meine, in der bereits keine Postings mehr stehen? Das ist doch nichts an Speicherplatz, udn wenn dafür keien Plattenzugriffe notwendig sind(was nicht der Fall ist), dann ist es doch perfekt!
For allem dachte ich mir, spare ich mir so einen Plattenzugriff, daher HEAP.
Ja, aber. ;-)
Einerseits kannst Du in dieser Hinsicht wahrschein- lich doch eher an der mySQL-Konfiguration drehen (da mußt Du halt wirklich mal alle Variablen im Handbuch nachschlagen - das lohnt sich aber).
Hab ich ja, egal was ich da drehem das sind ja alles nur obergrenzen die mir nicht be der ersten Suche helfen, sondern nur nachfolgende Suchen beschleunigen, da einfach mehr im Cahce gehalten werden kann. ich habe wirklich alle Paramterr verdoppelt, teilweise ver-4-facht, brint alles nicht! Kein Stück!
Und andererseits kann ein gut konfiguriertes Festplat- tensystem die Sache auch beschleunigen, vermute ich.
Ja, sicher, aber das habe ich hier nicht! Wie schon beschrieben. Ich kann das alles später mal unter Windows laufen lassen, die Platte ist rel. neu und über 133 ATA angebunden, mal gucken wie sich das auswirkt.
Das ist da immer nur eine Ergebnistabelle mit allen Feldern außer dem eigentlichen Postings, das hat der Fulltext ja bereits durchsucht und das kostet mit riesigem Abstand die meiste Performance.
Völlig richtig: So wenige Spalten mitnehmen wie nötig. Lieber die SELECT-Felderliste dynamisch berechnen, als einfach "*" hinschreiben etc.
Nltig ist im Prinzip nur ID und time, sollte ich die anderen Felder wie "autor" und "titel", dic ich ja später brauche aus der großen Tabelle joinen?
Da ich das Sortieren in meiner Anwendung mache, habe ich durch eine temporäre MYISAM-Tabelle keinerlei Nachteile gegenüber HEAP.
Aber ich dachte, HEAP wird im RAM abgelegt, und MyISAM auf der Festplatte! selbst bei einer schnellen Platte sollte das schlechter sein. Ich habe die Statemnents nicht evrändert, udn mal HEAP gegen MyISAM ausgetauscht, dann wird es 50% langsamer(das abfragen der Tabelle), das Create kann ich schlecht messen. Die Tabelle wird ja auch nur einmal gebraucht, also wäre es totale Zeitverschwendung eine Index anzulegen, und sonst bietet mir MyISAM hier keine Vorteile, im Gegenteil wie gesagt.
Du erinnerst Dich vielleicht, daß ich Dich gefragt hatte, ob Du Schreibzugriffe auzf der Festplatte wäh- rend Deiner Suchmaschinen-Abfragen beobachten kannst? Das solltest Du unbedingt prüfen.
Ja, aber das habe ich nicht geschafft zu prüfen.
Bei mir war das nämlich eine schreckliche Performance- Bremse, daß mySQL die temporären Tabellen auf die Festplatte geschrieben hat - weil es einen Pfad dafür vorkonfiguriert hatte, von dem es hoffte, dort eine RAM-Disk zu finden ... jetzt haben wir dort eine.
Daher dachte ich an HEAP!
Das letzte Problem besteht jetzt eigentlich in dem Index-Cache, oder wie auch immer das Ding heißt. Wie gesagt, beim ersten mal über 20 Sekunden, beim 2. mal 10, beim 3. mal 4 und danach immer zw. 0,2 und 0,4.
Welche IO-Zugriffsraten hast Du während dieser Zeit? (Siehe auch den vorherigen Absatz.)
Das versteh ich wie gesagt noch nicht richtig. Bei der Eingabe von "top" erhalte ich z.B.:
2:25am up 29 min, 1 user, load average: 0,10, 0,24, 0,22 89 processes: 86 sleeping, 2 running, 1 zombie, 0 stopped CPU states: 19,9% user, 1,7% system, 0,0% nice, 78,2% idle Mem: 255412K av, 251120K used, 4292K free, 0K shrd, 1772K buff Swap: 522104K av, 0K used, 522104K free 160248K cached
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND 1030 root 5 -10 62476 12M 5584 S < 15,5 5,0 1:00 X 1239 root 15 0 9128 9124 6968 R 5,1 3,5 0:01 gnome-terminal 1264 root 15 0 988 988 780 R 0,3 0,3 0:01 top 1127 root 15 0 6032 6028 5084 S 0,1 2,3 0:01 magicdev 1131 root 15 0 10996 10M 8504 S 0,1 4,3 0:01 gnome-panel 1 root 15 0 480 480 428 S 0,0 0,1 0:04 init 2 root 15 0 0 0 0 SW 0,0 0,0 0:00 keventd 3 root 15 0 0 0 0 SW 0,0 0,0 0:00 kapmd 4 root 34 19 0 0 0 SWN 0,0 0,0 0:00 ksoftirqd_CPU0 [...]
Da she ich nicht von IO, und auch in der Hilfe steht nichts dazu.
Schau Dir mal mit "top" die IOWAIT-Zeiten an - wenn die dramatisch hoch gehen, dann kommt Deine Festplatte nicht mit.
s.o.
Wäre das, was Du da tust, eine richtig teure kommer- zielle Anwendung, dann würde ich sagen: Hau 8 GB RAM in die Kiste rein und konfiguriere mySQL so, daß es den FULLTEXT-Index komplett im RAM halten kann ...
Wenn ich denn mal wüßte welche Variable ich hierfür verstellen müßte, da gibt es so viele...
Das hieße vermutlich am Ende eine Durchschnitts- Suchzeit von 5 oder mehr Sekunden! Das kann so doch nicht funktionieren!
Richtig. Irgendwas an Deiner Konfiguration tut noch nicht.
Ich denke, in Sachen SQL hast Du alles ausgereizt; jetzt geht es ans mySQL-Tuning und darum, die dann noch unvermeidlichen Festplattenzugriffe so schnell wie möglich zu machen.
Ja, aber was können die MySQL Parameter da machen? Ich kann lediglich bestimmen wieviel im RAM steht, aber sonst?
Was meinst Du wie ich das verändern kann? Die Zeit geht bei
CREATE TEMPORARY TABLE temp_tabelle TYPE=HEAP
Ich zweifele daran, daß HEAP eine gute Idee ist.
wieso?
MATCH (topic,title,name,body) AGAINST ('Andreas')
Das ist bestimmt nicht gut.
Das war auch nur ein Beispiel, ein Suchstring a la "+Andreas + Datenbank"
MATCH (topic,title,name,body) AGAINST ('fsockopen()')
Der zweite Suchbegriff ist um Größenordnungen besser!
Ja, aber was der User eingibt kann ich ja schlecht wissen, vielleicht kann ich es umsortieren, sollte nicht allzulange dauern. Was mich aber am meisten stört, fsockopen würde ich nicht suchen können, da teilstring. Das ist das Größte Problem den ich muß ja Fulltext verwenden. Das wäre mir noch wichtiger als Phrasen.
Ein normales "WHERE" für den "Andreas", selbst eines mit LIKE über die gesamte Story, hat Chancen, besser zu sein. Mach mal einen direkten Vergleich ...
Weiß ich das voreher? Und ein LIKE über die Posting-Spalte dürfte sehr lange dauern!
LIMIT 0, 1000
Das wirkt zu spät.
lustig! Wie soll ich das vorher begrenzen?
Du berechnest zunächst einige tausend Treffer mit "Andreas", joinst ("AND") diese gegen ein paar Dutzend "fsockopen" (das ist teuer!) und erst danach begrenzt Du auf 1000 Stück, die Du aber nach dem JOIN bestimmt schon nicht mehr hast.
Klar, aber das Scipt kann nunmal nicht so schlau sein wie Du ;-)
Yep. Mach eine Statistik über alle Worte Deiner Daten- bank - und setze "Andreas" auf die Schwarze Liste. ;-)
Das dumnme an der schwarzen liste, ich gebe "Andreas" ja nicht nru zum Spaß ein! Das soll ja auch Auswirkungen auf das Ergebnis haben!
SELECT * FROM temp_tabelle ORDER BY time DESC LIMIT 0, 100 dagegen dauert es wie gesagt imme unter 0,001 Sekunden.
Klar - da ist das Problem auch schon gelöst.
Wo soll ich es sonst lösen?
Was könnte man hier machen? Ich denke das ist das letze Problem,
Aber auch eines der schwierigsten. Du bräuchtest eine Bewertungsfunktion, um gute WHERE- Klauseln zu berechnen, bevor Du sie ausführst. Eine Schwarze Liste wäre ein möglicher Weg dorthin.
Mach mal einen Test (jeweils mit mySQL-Neustart vorher):
Neustart von MYSQL reicht nicht, ich muß renooten und das ist mervig ;-)
Ist die Dauer dieser Query abhängig von der Reihenfolge (!) der beiden Suchbegriffe?
Ich meine nein, aber habe jetzt keinen Beweise da ich nicht neu booten will ;-)
Mach mal einen zweiten Test: Definiere einen zusätz- lichen (!) FULLTEXT-Index über den Author und generie- re die WHERE-Klausel so, daß sie "Andreas" nur in diesem zweiten FULLTEXT sucht (was man in der alten Suche über die Eingabe "author:Andreas" ausdrücken kann). Ist das schneller? Ich denke, ja - weil dann nur noch der seltenere Begriff im großen FULLTEXT-Index gesucht werden muß.
mache ich später, meinst Du das wäre besser als meine instr() Varianteß Wie gesagt kostet die so gut wie nicht!
Du wirst immer noch irre viele Treffer dabei finden und JOINen müssen, aber es sind weniger als bisher.
mit regexp arbeiten, das geht ja in mysql
Versuche es - aber rechne damit, daß dasselbe passiert wie bei LIKE %...%: Es werden wahrscheinlich keinerlei Indexzugriffe mehr möglich sein.
Ist ja auch egal, ich meine das jetzt für die temporäre Tabelle, daher wollte ich die etwas größer machen(max 1000), damit ich evtl hier so filtern kann, was sehr schnell ist, aber evtl einige Ergebnisse ausschließt.
Grüße Abdreas