2013-02-21 6 views
5

ich eine einfache Tabelle haben ->Verwendung von IN() Klausel führt filesort

id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY 
by_id INT UNSIGNED NOT NULL 
posted_on INT UNSIGNED NOT NULL 

ist mein Tisch Motor MyISAM.

Ich habe einen mehrspaltigen Index combo1 auf by_id,posted_on,id

Ich betreibe diese Abfrage genannt ->

EXPLAIN SELECT * FROM books 
     WHERE by_id = '1' AND posted_on = '0' 
     ORDER BY id DESC LIMIT 7; 

Die Extra Spalte sagt Using where und Schlüsselspalte sagt combo1

Aber, wenn ich laufen Diese Abfrage ->

EXPLAIN SELECT * FROM books 
     WHERE by_id IN(1,7,10) AND posted_on = '0' 
     ORDER BY id DESC LIMIT 7; 

Die Extra Spalte sagt Using where; Using filesort und Schlüssel Spalte sagt combo1.

Warum tritt ein filesort im zweiten Fall auf, obwohl der QEP zeigt, dass der Optimierer den Index combo1 verwendet, in dem 'id' indiziert ist.

Antwort

6

Der Index ist ein B + Baum. Das bedeutet, dass unter der by_id 1 alle Datensätze mit posted_on 0 und by_id 1 vorhanden sind und Sie dann alle IDs für diese Datensätze haben. Unter der by_id 7 haben Sie jedoch einen anderen Baumzweig, der Datensätze mit posted_on 0 enthält und sie die Datensätze mit ihren IDs enthält.

Wenn Sie in in haben, erhalten Sie 3 verschiedene Zweige des Baumes, Sie müssen sie zusammenführen und verwenden, da ids mit 1,2,4 unter by_id 1, aber 3,5 unter by_id 10 sein können ; MySQL ruft 1,2,4,3,5 ab und muss sie zurückgeben.

Im ersten Fall gibt es nur einen Zweig, und jeder Zweig bereits sortiert ist

+0

Dank große Erklärung @Darhazer – sanchitkhanna26

+0

bitte sagen, ob ich dann 'id' aus combo1 Index entfernen sollte .. @Darhazer – sanchitkhanna26

+0

Nun, ich bin mir nicht sicher, ob MySQL den Vorteil nutzt, dass die Zweige bereits geordnet sind und merge_sort anwendet oder nicht; vielleicht hängt es auch von der Version ab. Ohne korrektes Benchmarking würde ich die ID im Index beibehalten. Wenn die Tabelle andererseits InnoDB ist, wird ID am Ende jedes sekundären Indexes eingefügt. Dies wird bei der Sortierung nur in MySQL 5.6 berücksichtigt, wenn ich mich richtig erinnere. –

Verwandte Themen