ORDER BY … LIMIT処理を最適化する
数万行のテーブルをORDER BYしているSQLが遅い。EXPLAINすると「Using Filesort」の文字が。
「Using Filesort」とは、テンポラリファイルを使ってソートしようとしているとの説明なので、INDEXでFetchできれば解決します。
ところが、
MySQL で ORDER BY の解決にインデックスを使用できない場合は以下のとおりです(この場合も MySQL は WHERE 節の条件に一致するレコードの検索にインデックスを使用します)。
- 複数のキーに対して ORDER BY を実行する場合。
> SELECT * FROM t1 ORDER BY key1,key2
- 連続しないキー部分に対して ORDER BY を実行する場合。
> SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2
- ASC と DESC が混在している場合。
> SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 ASC
- レコードの取り出しに使用されるキーが ORDER BY の実行に使用されるキーと異なる場合。
> SELECT * FROM t1 WHERE key2=constant ORDER BY key1
- ORDER BY で多くのテーブルとカラムを結合していて、それら全てがレコードの取り出しに使用される最初の非 const テーブルではない場合(これは EXPLAIN で出力される最初のテーブルで、かつ、const メソッドを使用していないテーブル)。
- ORDER BY と GROUP BY 式が異なる場合。
MySQL による ORDER BY の最適化
- 使用されたテーブルインデックスが、並び順にレコードを格納していないインデックスタイプの場合(HEAP テーブルの HASH インデックスなど)。
というわけで、MySQLのORDER BYするカラムにてINDEXを使うにはちょいと制限が多い。
「まあ、バッチシ当てはまってしまった場合はどうしようもない」
と諦めかけていましたが、id:kazuhookuさんがテクニックを残しておいてくれてました。
単一テーブルのSELECTで自己結合するのは気が引ける部分がモチロンありますが、速度には変えられない。
というわけで、ほんまにありがとうございます。