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 式が異なる場合。
  • 使用されたテーブルインデックスが、並び順にレコードを格納していないインデックスタイプの場合(HEAP テーブルの HASH インデックスなど)。
MySQL による ORDER BY の最適化

というわけで、MySQLのORDER BYするカラムにてINDEXを使うにはちょいと制限が多い。
「まあ、バッチシ当てはまってしまった場合はどうしようもない」


と諦めかけていましたが、id:kazuhookuさんがテクニックを残しておいてくれてました。

MySQL の filesort プチテクニック

単一テーブルのSELECTで自己結合するのは気が引ける部分がモチロンありますが、速度には変えられない。
というわけで、ほんまにありがとうございます。