3

次のスキーマを持つテーブルがあります

Id、INT、主キー

クエリ ID、 INT

CreatedTime、 DateTime

そして、複合インデックス(QueryId、CreatedTime)を作成しました

Explain select * from test where queryid in (1,6) order by createdtime desc を実行すると、どうしてでしょうか

私はまだファイルソートを持っている次のものを手に入れますか? ファイルソートを削除するにはどうすればよいですか? 「where の使用; filesort の使用」

結果の説明

4

1 に答える 1

1

そのクエリに使用できるインデックスを実際に作成していません。

インデックスは、ルックアップと左端の列から右への並べ替えにのみ使用できます。役に立たないものが検出されるとすぐに、残りのインデックスは無視されます。

あなたはあなたの出力を投稿しませんでしたEXPLAINが、インデックスが調べられていて QueryId が であるINT場合、 = 4 が見つかりKey_len、左端の 4 バイト (QueryId) のみがオプティマイザーにとって有用であることを意味すると思います。

QueryId で単一の値を選択している場合にのみ、QueryId でレコードを抽出し、CreatedTime でソートするための (QueryId,CreatedTime) のインデックス。これを行うと、インデックスはその QueryId に一致する行を返し、既に CreatedTime で並べ替えられており、オプティマイザーはこれを認識します。

逆に、QueryId の複数の値を探す場合、インデックスによって返される行は、QueryId によってソートされ、次にQueryId の各グループ内の CreatedTime によってソートされて返されます...したがって、CreatedTime 値は本質的に役に立たない場所でソートされるため、さらにファイルソートが必要です。注文。ORDER BYもちろん、QueryId、CreatedTimeの場合、ファイルソートはなくなるはずですが、それはおそらくあなたが望むものではありません。

(CreatedTime,QueryId) のインデックスも役に立ちません。QueryId が左側にないためです。行数が非常に少ない場合を除き、サーバーは CreatedTime で事前に並べ替えられた行をプルできますが、 QueryId に一致する値を見つけるには、すべての行をスキャンする必要があります。

つまり、そのようなクエリに対して完全にインデックスを作成することはできず、Using filesort常に回避できるものではありません。

于 2013-10-17T05:02:40.220 に答える