Hi Andreas,
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,
es geht nicht darum, wo die Daten gespeicher werden, sondern wie. Das hast Du doch am Sortieren gemerkt: Sortieren im RAM ist furchtbar teuer, wenn die Datenmenge groß genug ist, weil das ein n*log(n)-Algorithmus ist.
und in der Doku steht doch auch das es ganeu dazu gedacht ist, also nicht ganz, aber so ähnlich ;-)
Eben. Das ist der Grund für mein "ja, aber".
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!
Siehe oben: Auch sehr viele sehr kleine Daten brauchen zum Sortieren sehr viele sinnlose Vergleiche.
Und so, wie ich den HEAP verstanden zu haben glaube, ist der Sinn der Sache, daß dabei implizit ein Index aufgebaut wird - genau das, was wir vermeiden wollen, weil dafür eine Sortierung notwendig ist. MYISAM im RAM muß für Deinen Zwecke besser sein als HEAP.
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 beschleu- nigen, da einfach mehr im Cache gehalten werden kann. ich habe wirklich alle Paramterr verdoppelt, teilweise ver-4-facht, brint alles nicht! Kein Stück!
Du sollst auch nicht alle Parameter verdoppeln - das kostet RAM und macht die Sache langsamer. Du sollst den richtigen Parameter finden und ihn verzehnfachen.
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?
Alles, was Du später brauchst, ist "nötig".
Bedenke, daß der JOIN auch wieder implizit eine Sor- tierung braucht - wenn Du es schaffst, diesen JOIN nach der Limitierung zu machen, dann ist er nicht so teuer, ansonsten würde ich ihn zu vermeiden suchen.
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!
Deshalb hatte ich in Dir in einem meiner vorherigen Postings den Link auf die mySQL-Doku gezeigt, wo steht, wo diese Daten auf der Festplatte gespeichert werden. Wenn Du diesen Pfad auf eine RAM-Disk legst, hast Du Deine MYISAM-Tabellen im RAM ... und brauchst kein HEAP mehr.
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.
Du kannst alles messen. Liste Dir die einzelnen SQL-Statements auf (zerlege das, was Du bei CREATE TABLE AS SELECT ... in einem Schritt machst, wieder in zwei Schritte) und tippe sie über die mySQL- Kommandozeile nacheinander ein. Du bekommt dort eine Zeitmessung für jeden einzelnen Schritt.
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.
Gerade weil Du keinen Index brauchst, solltest Du MYISAM nehmen - und nicht HEAP.
Das solltest Du unbedingt prüfen. Ja, aber das habe ich nicht geschafft zu prüfen.
"top" hast Du aber? Normalerweise solltest Du eine IOWAIT-Anzeige im einstelligen Prozentbereich haben. Wenn die während einer Abfrage deutlich zweistellig wird, dann bremst Deine Platte das Systen.
RAM-Disk zu finden ... jetzt haben wir dort eine. Daher dachte ich an HEAP! http://www.mysql.com/doc/en/Temporary_files.html
"Ja, aber". Du schüttest das Kind mit dem Bade aus. MYISAM auf RAM-Disk ist RAM ohne HEAP-Struktur.
Das versteh ich wie gesagt noch nicht richtig. Bei der Eingabe von "top" erhalte ich z.B.:
CPU states: 19,9% user, 1,7% system, 0,0% nice, 78,2% idle
Was ist denn das schon wieder für ein komisches "top"? Wo ist da die IOWAIT-Spalte? Genau die brauchst Du ...
Da she ich nicht von IO, und auch in der Hilfe steht nichts dazu.
Gnlpfts. Mein "top" zeigt mir mehr an. (http://www.sunmanagers.org/pipermail/sunmanagers/2001-November/008101.html)
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...
Ich habe gerade mal das mySQL-Handbuch überflogen ...
Ich fürchte, Du wirst das gesamte Kapitel 5 einmal linear durchlesen müssen - nicht, um es komplett zu verstehen, sondern um zu lernen, welche Themen dort behandelt werden. Das ist ein Ideengeber ohne Ende.
Konkreter Versuch - setz mal diesen Wert hier so hoch, wie nur irgend möglich bei Dir:
"key_buffer_size" Index blocks are buffered and are shared by all threads. key_buffer_size is the size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common. If you, however, make this too big (for instance more than 50% of your total memory) your system may start to page and become extremely slow. Remember that because MySQL does not cache data reads, you will have to leave some room for the OS filesystem cache. You can check the performance of the key buffer by doing show status and examine the variables Key_read_requests, Key_reads, Key_write_requests, and Key_writes. The Key_reads/Key_read_request ratio should normally be < 0.01. The Key_write/Key_write_requests is usually near 1 if you are using mostly updates/deletes but may be much smaller if you tend to do updates that affect many at the same time or if you are using DELAY_KEY_WRITE. See section 4.5.6 SHOW Syntax. To get even more speed when writing many rows at the same time, use LOCK TABLES. See section 6.7.2 LOCK TABLES/UNLOCK TABLES Syntax.
Ja, aber was können die MySQL Parameter da machen? Ich kann lediglich bestimmen wieviel im RAM steht, aber sonst?
Vieles. Beispiel (jetzt nicht für SELECT, aber für INSERT):
"ft_max_word_len_for_sort" The maximum length of the word in a FULLTEXT index to be used in fast index recreation method in REPAIR, CREATE INDEX, or ALTER TABLE. Longer words are inserted the slow way. The rule of the thumb is as follows: with ft_max_word_len_for_sort increasing, MySQL will create bigger temporary files (thus slowing the process down, due to disk I/O), and will put fewer keys in one sort block (again, decreasing the efficiency). When ft_max_word_len_for_sort is too small, instead, MySQL will insert a lot of words into index the slow way, but short words will be inserted very quickly.
Das ist also ein Wert, mit dem Du den FULLTEXT-Indexer auf Deine "Sprache" feintunen kannst.
Ich zweifele daran, daß HEAP eine gute Idee ist. wieso?
Weil Du die Fähigkeit eines HEAP, als Baum gespeichert zu werden, bezahlen mußt, aber nicht ausnutzt.
MATCH (topic,title,name,body) AGAINST ('Andreas') Das ist bestimmt nicht gut. Das war auch nur ein Beispiel, ein Suchstring a la "+Andreas + Datenbank"
Mein Einwand ist aber prinzipieller Natur: Deine konkreten WHERE-Klauseln könnten besser sein.
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.
Genau das meinte ich. Eine Funktion, die Dir zu jedem Suchbegriff dessen Häufigkeit berechnet, ist nicht schwer zu bauen; basierend auf dieser kannst Du dann "nutzlose" Terme herausnehmen, statt damit den Index- zugriff durchzuführen und in Treffern zu ertrinken.
Was mich aber am meisten stört, fsockopen würde ich nicht suchen können, da teilstring.
Das habe ich nicht verstanden.
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?
Ja, das weißt Du vorher, wenn Du eine Tabelle mit den beiden Spalten "begriff" und "haeufigkeit" hast, über "begriff" ein PRIMARY KEY liegt und Du für jeden Begriff einen SELECT dort investierst.
Die Tabelle muß gar nicht inkrementell gepflegt sein
- die relative Häufigkeit der Suchbegriffe ändert sich nur langsam. Es reicht, wenn Du die einmal im Monat aufbaust. Und diese Tabelle sollte ein HEAP sein!
Und ein LIKE über die Posting-Spalte dürfte sehr lange dauern!
Nicht, wenn Du nur ganz wenige Postings zu prüfen hast. Der Unterschied zwischen den Suchbegriffen muß mindestens eine Zehnerpotenz ausmachen, schätze ich.
LIMIT 0, 1000 Das wirkt zu spät. lustig! Wie soll ich das vorher begrenzen?
Indem Du die einzelnen Schritte voneinander trennst.
Klar, aber das Scipt kann nunmal nicht so schlau sein wie Du ;-)
Doch. Das muß es sogar. Das ist der Trick an der Sache.
Yep. Mach eine Statistik über alle Worte Deiner Datenbank - 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!
Hat es auch - Du sollst ja "Andreas" nicht ignorieren, sondern diesen Begriff nur nicht mit MATCH abfragen, sondern ganz normal mit LIKE. Und am besten auch nicht im Posting-Body, sondern nur im Author - es liegt an Deinem Eingabeformular, dem Anwender zu erleichtern, Dir diese eingeschränkte Bedeutung zu sagen. Je mehr Informationen der Anwender in diesem Formular eingibt, desto bessere SELECT- Statements kannst Du daraus generieren.
Mach mal einen Test (jeweils mit mySQL-Neustart vorher): Neustart von MYSQL reicht nicht, ich muß renooten und das ist mervig ;-)
Das macht nichts. Es geht um das prinzipielle Verständnis. (Alternativ kannst Du auch das ganze mySQL-Handbuch lesen ...)
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 ;-)
Investiere einen Bootvorgang dafür. Das lohnt sich.
mache ich später, meinst Du das wäre besser als meine instr() Varianteß Wie gesagt kostet die so gut wie nicht!
Diese Aussage glaube ich nicht, solange sie unabhängig von der Treffermenge ist.
Bei vielen Treffern kostet jede Operation etwas. Entscheidend ist, ob die Kostenfunktion linear oder überlinear mit der Anzahl der Treffer wächst - und in dieser Hinsicht ist Sortieren fast immer der worst case.
Viele Grüße Michael