2012-02-06 15 views
0

私はそのインデックスは、 "順" の世話をするだろう(名前、のcreated_at)とIMySQLインデックスは自動的にORDER BYを考慮しますか?

SELECT * WHERE name='blah' and created_at="blah" ORDER BY created_at DESC 

にインデックスを作成した場合は?

もしそうでなければ、どのようにインデックスを作成すればORDER BYがより効率的になりますか?

+0

「インデックスで注文が処理されるのですか」とはどういう意味ですか? –

答えて

0

可能であれば、インデックスは順序付けに使用されます。しかし、あなたの例では、すべての結果がcreated_atに "blah"の値を持つので、何も注文することはありません。あなたは次のことを意味しましたか?上記の場合

SELECT * WHERE name='blah' ORDER BY created_at DESC 

、インデックス(名前、のcreated_at)「をカバーする」化合物は、WHERE選択及び分類の両方に使用されるであろう。

デフォルトのインデックスタイプはbtreeで、ツリーの先頭にはすべてnameの値があります。各ブランチの下には、それぞれcreated_atが注文されます。

nameと等しいインデックスのセクションを検索し、その下の残りのブランチを使用してcreated_atの結果の主キーを返すインデックスとしての注文。

レコードがすでに返されているため、さらに並べ替える必要はありません。

+0

あなたの例では、複合インデックス(name、created_at)を作成する必要があります。私が単にインデックス名を指定すると、クエリはソートに最適化されません。コレク? – user847495

+0

これはMySQLのバージョンによって多少異なります。 MySQLのそれ以降のバージョンでは、注文のために別のインデックスを利用することができます。ただし、(name、created_at)を持つ複合インデックスがある場合は、すべての場合に機能します。 –

0

BTREEインデックス(デフォルト)を使用して並べ替えることができます。索引を使用するかどうかは、オプティマイザが把握しているものによって異なります。

クエリの前にEXPLAINを使用してこれを確認できます。

このクエリでは、ORDER BYは特定のcreated_atを探すほど大きな影響を与えません。

クエリは、より多くのこのようなものだった場合:

SELECT * FROM foo WHERE name='blah' ORDER BY created_at DESC 

あるいは

SELECT * FROM foo WHERE name='blah' and created_at BETWEEN 'a' AND 'z' ORDER BY created_at DESC 

あなたが(そのために)名前とはcreated_atの両方に単一のインデックスを使用してより良い結果を得るでしょう。まず索引を使用して名前と一致させ、同じ索引を使用して結果をソートします。

ALTER TABLE foo ADD INDEX (`name`, `created_at`) 

もちろん、これは引き続きEXPLAINで検証する必要があります。データベース・オプティマイザは、正確な問合せ値と見積もられるデータ量に応じて最適なものと判断します。