Ich habe zwei Fragen,
select some_other_column
from `table`
order by primary_index_column asc
limit 4000000, 10;
und
select some_other_column
from `table`
order by secondary_index_column asc
limit 4000000, 10;
Beide geben 10 Zeilen zurück; Der erste dauert 2,74 Sekunden und der zweite 7,07 Sekunden. some_other_column
ist kein Teil eines Index. primary_index_column
ist die Primärschlüsselspalte; secondary_index_column
hat einen B-Tree-Index und eine Kardinalität von 200 (laut MySQL).
Hier sind die explain
Ergebnisse:
mysql> explain select some_other_column from `table` order by primary_index_column limit 4000000, 10;
+----+-------------+---------+-------+---------------+---------+---------+------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+------+---------+-------+
| 1 | SIMPLE | table | index | NULL | PRIMARY | 4 | NULL | 4000010 | |
+----+-------------+---------+-------+---------------+---------+---------+------+---------+-------+
mysql> explain select some_other_column from `table` order by secondary_index_column limit 4000000, 10;
+----+-------------+---------+------+---------------+------+---------+------+---------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+---------+----------------+
| 1 | SIMPLE | table | ALL | NULL | NULL | NULL | NULL | 4642945 | Using filesort |
+----+-------------+---------+------+---------------+------+---------+------+---------+----------------+
Warum wählt MySQL diesen spezifischen Ausführungsplan für die zweite Abfrage? Ich verstehe nicht, warum es den Index für die erste Abfrage verwenden kann, aber nicht für die zweite Abfrage.
quelle
LIMIT 10 OFFSET 4000000
Teil, was bedeutet, dass die SQL-Engine irgendwie (indexiert oder anderweitig) 4 Millionen (und 10) Zeilen abrufen und die ersten (!) 4 Millionen davon verwerfen muss. Seien Sie nicht überrascht, wenn die Verwendung des Index nicht oder nur langsam erfolgt.COMMON THINGS
, um das Optimierungsverhalten hinter Ihren Abfragen zu erläutern.Gemäß der MySQL - Dokumentation auf der Optimierung von
order by
Abfragen ,Nach meinem Verständnis von InnoDB werden die Zeilen in der Reihenfolge des Primärschlüssels gespeichert. Daher sind sie für Sekundärindizes nicht in Ordnung.
quelle
some_other_column
Informationen nicht imsecondary_index_column
Index gespeichert sind , klicken Sie auf OK. Das erklärt, warum ein (Deckungs-) Index von(secondary_index_column, some_other_column)
, wie von Rolando vorgeschlagen, die Informationen enthält und hilfreich sein kann.