Ich verstehe das nicht.
Ich habe eine Tabelle mit diesen Indizes
PRIMARY post_id
INDEX topic_id
FULLTEXT post_text
Die Tabelle enthält (nur) 346 000 Zeilen. Ich versuche 2 Abfragen durchzuführen.
SELECT post_id
FROM phpbb_posts
WHERE topic_id = 144017
AND post_id != 155352
AND MATCH(post_text) AGAINST('http://rapidshare.com/files/5494794/photo.rar')
dauert 4,05 Sekunden während
SELECT post_id
FROM phpbb_posts
WHERE topic_id=144017
AND post_id != 155352
AND post_text LIKE ('%http://rapidshare.com/files/5494794/photo.rar%')
dauert 0,027 Sekunden.
EXPLAIN zeigt, dass der einzige Unterschied in möglichen_ fulltext
Schlüsseln besteht ( hat post_text enthalten, LIKE
nicht)
Das ist wirklich seltsam.
Was steckt dahinter? Was passiert im Hintergrund? Wie kann LIKE
man so schnell sein, wenn man keinen Index verwendet, und FULLTEXT so langsam, wenn man seinen Index verwendet?
UPDATE1:
Eigentlich dauert es jetzt ungefähr 0,5 Sekunden, vielleicht war die Tabelle gesperrt, aber wenn ich die Profilerstellung einschalte, zeigt sich, dass die FULLTEXT-INITIALISIERUNG 0,2 Sekunden gedauert hat. Was geht?
Ich kann meine Tabelle mit LIKE
10x pro Sekunde abfragen , mit Volltext nur 2x
UPDATE2:
Überraschung!
mysql> SELECT post_id FROM phpbb_posts WHERE post_id != 2 AND topic_id = 6 AND MATCH(post_text) AGAINST ('rapidshare.com');
Empty set (0.04 sec)
Also frage ich, wie ist das möglich?
Zusätzlich,
SELECT count(*) FROM phpbb_posts WHERE MATCH(post_text) AGAINST ('rapidshare.com')
ist sehr langsam. Kann Volltext kaputt sein?
UPDATE3:
Was zum Teufel?
SELECT forum_id, post_id, topic_id, post_text FROM phpbb_posts WHERE MATCH(post_text) AGAINST ('rapidshare.com') LIMIT 0, 30;
dauert 0,27s während
SELECT count(*) FROM phpbb_posts WHERE MATCH(post_text) AGAINST ('rapidshare.com') LIMIT 0, 30;
dauert mehr als 30 Sekunden! Was läuft hier falsch?
quelle
Antworten:
Ich denke, das Problem kann auf das Vorhandensein des FULLTEXT-Index selbst zurückzuführen sein.
Jedes Mal, wenn eine Abfrage mit einem FULLTEXT-Index vorliegt, führt das MySQL Query Optimizer dazu, dass die Abfrage in einen vollständigen Tabellenscan umgewandelt wird. Ich habe das über die Jahre gesehen. Ich habe auch einen früheren Beitrag über dieses unbedeutendste Verhalten in FULLTEXT-Indizes geschrieben .
Möglicherweise müssen Sie zwei Dinge tun:
REFACTOR DIE FRAGE
Hier ist Ihre ursprüngliche Anfrage
Sie müssen die Abfrage wie folgt umgestalten:
ERSTELLEN SIE EINEN NEUEN INDEX
Zur Unterstützung benötigen Sie einen Index
subqueryA
. Sie haben bereits einen Index fürtopic_id
. Sie müssen es wie folgt ersetzen:Versuche es !!!
UPDATE 2012-03-19 13:08 EDT
Versuchen Sie dies zuerst
Wenn dies schnell ausgeführt wird und eine kleine Anzahl von Zeilen zurückgegeben wird, versuchen Sie diese verschachtelte Unterabfrage:
UPDATE 2012-03-19 13:11 EDT
Vergleichen Sie die Laufzeit davon:
mit diesem
Wenn die Laufzeit gleich ist, wird die MATCH-Klausel in jeder Zeile ausgeführt. Wie ich bereits erwähnt habe, führt die Verwendung von FULLTEXT-Indizes dazu, dass alle vom MySQL Query Optimizer versuchten und bereitgestellten Vorteile zunichte gemacht werden.
quelle
post_id
verwirrt? Warum funktioniert die LIKE-Abfrage auch ohne Index für diese Spalten (topic_id, post_id)? Warum wählt MYSQLtopic_id = 144017 AND post_id != 155352
diese Ergebnisse nicht einfach intelligent aus und durchsucht sie dann einfach? Und was ist, wenn 100.000 Zeilen meine Volltextsuchzeichenfolge enthaltenpost_text
? Würde es nicht alle auswählen?