あなたは、MySQLだけにインデックスを使用して、せいぜい最初の10行を読み、これらを並べ替えてくれていると思うかもしれません。残念ながら、オプティマイザはこの時点でlimit
を考慮していないため、そうではありません。 explain select ...
を使用すると、MySQLがフルテーブルスキャン("ALL"
)を実行することがわかります。すべての未使用部分限り、ORDER BYが正確インデックスと一致しない場合であっても
指標を用いることもできる。
documentationはorder by
最適化するためにインデックスを使用することができるように条件を説明します索引とすべての余分なORDER BY列はWHERE句の定数です。
3番目の列がこれを満たしていません。したがって、このクエリはこのインデックスを使用しません。これは、他のものには役に立たないとは限りません。
は、MySQL 5.6以来、しかしそこにある対応するためにfilesort priority queue optimizationいわゆるlimit
:MySQLはまだテーブル全体を読み込みますが、それは(時間のかかるプロセスになります)、表全体をソートしませんが、停止します最初の行が何であるかを知っているときには、クエリを受け入れやすくなります。
しかし、あなたは、あなたが考えている正確に何を行うには、クエリを書き直すことができます。これは、そのインデックスを使用して最初の10行を読み、そしてちょうどこれらをソートします
SELECT * FROM
(select * from table ORDER BY one, two LIMIT 10) sub
order by one, two, three limit 1;
。もちろん、最大で10行しか持たないことが確実であれば正しく動作します。
可能な最大行数を知ることとは別にクエリを最適化するより一般的な方法は、たとえば次のようになります。
SELECT * FROM table
where one = (select min(one) from table)
order by one, two, three limit 1;
これはone
(インデックスを使用して)最初で唯一のこれらの行を考慮するための最低値を調べることにより、読み、filesortedする必要がある行の数を減らすためにインデックスを使用します。同様に、two
の条件を含めることができます。
または、インデックスに3つの列をすべて使用することもできます(ただし、3番目の列のサイズにもよりますが、これを行わないと意味があります)。この種の最適化は、ある時点で追いつく傾向があります。例:最初のメソッドを使用し、2年後に11行が可能になります。コード(コード)に暗黙の条件があることを覚えておく必要があります。
私は「テーブルスキャン」の主張に異議を申し立てます。 –