Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL verwendet keine Indizes (Using filesort), wenn ORDER BY verwendet wird

Sie können in diesem Fall keinen Index verwenden, da Sie einen RANGE verwenden Filterbedingung.

Wenn Sie so etwas verwenden würden:

SELECT  *
FROM    values_table this_
WHERE   this_.value1 = @value
ORDER BY
        value2
LIMIT 10

, und erstellen Sie dann einen zusammengesetzten Index für (VALUE1, VALUE2) sowohl zum Filtern als auch zum Bestellen verwendet werden.

Aber Sie verwenden eine Bereichsbedingung, deshalb müssen Sie die Bestellung trotzdem durchführen.

Ihr zusammengesetzter Index sieht folgendermaßen aus:

value1 value2
-----  ------
1      10
1      20
1      30
1      40
1      50
1      60
2      10
2      20
2      30
3      10
3      20
3      30
3      40

, und wenn Sie 1 auswählen und 2 in value1 , erhalten Sie immer noch keinen ganzen sortierten Satz von value2 .

Wenn Ihr Index auf value2 ist nicht sehr selektiv (d.h. es gibt nicht viele DISTINCT value2 in der Tabelle), könnten Sie versuchen:

CREATE INDEX ix_table_value2_value1 ON mytable (value2, value1)

/* Note the order, it's important */    

SELECT  *
FROM    (
        SELECT  DISTINCT value2
        FROM    mytable
        ORDER BY
                value2
        ) q,
        mytable m
WHERE   m.value2 >= q.value2
        AND m.value2 <= q.value2
        AND m.value1 BETWEEN 13123123 AND 123123123

Dies wird als SKIP SCAN bezeichnet Zugriffsmethode. MySQL unterstützt es nicht direkt, aber es kann so emuliert werden.

Der RANGE access wird in diesem Fall verwendet, aber wahrscheinlich erhalten Sie keinen Leistungsvorteil, es sei denn DISTINCT value2 weniger als etwa 1% umfassen Zeilen.

Beachten Sie die Verwendung von:

m.value2 >= q.value2
AND m.value2 <= q.value2

statt

m.value2 = q.value2

Dies macht MySQL Führen Sie RANGE aus Überprüfung auf jeder Schleife.