2016-09-09 11 views
0

このクエリでキーを使用することを期待していました。このEXPLAINでキーが使用されないのはなぜですか?

mysql> DESCRIBE TABLE Foo; 
+-------+-------------+------+-----+---------+----------------+ 
| Field | Type  | Null | Key | Default | Extra   | 
+-------+-------------+------+-----+---------+----------------+ 
| id | bigint(20) | NO | PRI | NULL | auto_increment | 
| name | varchar(50) | NO | UNI | NULL |    | 
+-------+-------------+------+-----+---------+----------------+ 

mysql> EXPLAIN SELECT id FROM Foo WHERE name='foo'; 
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra            | 
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ 
| 1 | SIMPLE  | NULL | NULL | NULL   | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables | 
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ 

fooがnameに一意のインデックスを持っているのに、なぜインデックスはSELECTで使用されていませんか?

+1

WHEREは常にfalseを返すためです。それはドキュメントにあります..また、あなたのテーブルには 'foo'と一致するレコードはありません。 MySQLは小さなテーブルにインデックスを使用しません。なぜなら、I/Oペナルティが発生しないためです。索引をたどることなくそのようなレコードがないと結論づけることができます。 –

+0

http://dba.stackexchange.com/a/21265 – Drew

答えて

2

インポッシブル

のconstテーブル読んだ後に気づい:MySQLは全てのconst(およびシステム)を読みました(JSONプロパティ メッセージ)

テーブルをWHERE 句は常にfalseであることに注意してください。

とconstのテーブルの定義、Constants and Constant Tables題したページから:

MySQLの定数は、クエリ内の単なるリテラル以上の何かです。 また のように定義される定数テーブルの内容とすることができる次の

WHERE条件に制限されている、又は一つだけの行ゼロの行

テーブル式、 持つテーブル表の主キーの 列すべて、または 表の一意キー(NOT NULLとして定義されている一意の列であることを条件とします)のすべての列に対して、column = constantという形式の式が含まれます。

第2の参考文献は、ページと半分の長さです。それを参照してください。

const

CONST

テーブルは クエリの開始時に読み取られる最大1個の一致する行に有します。 1行しかないので、この行の の列の値は、残りのオプティマイザによって定数と見なすことができます。 constテーブルは非常に高速です。一度だけ読み取られるためです。

constは、PRIMARY KEYまたはUNIQUE インデックスのすべての部分を定数値と比較するときに使用されます。以下のクエリでは、tbl_nameは をconstテーブルとして使用できます。

SELECT * FROM tbl_name WHERE primary_key = 1;

SELECT * FROM tbl_name where primary_key_part1 = 1 AND primary_key_part2 = 2;

+1

TL; DRは、名前が単純な行値として扱われるのを防ぐために 'name!= 'foo''を試してください – spraff

0

上記テーブルFooのデータ量が非常に少ないためである可能性があります。このような場合、オプティマイザはインデックスを調べるのではなく、テーブルスキャンを実行することを選択します。 MySQL Documentationとして

明確

インデックスが言うには、レポートクエリがほとんどまたはすべての行を処理し、小さなテーブルに対するクエリ、または大きなテーブル にはあまり重要です。クエリ がほとんどの行にアクセスする必要がある場合は、インデックスを使用して よりも順番に読み込みが高速になります。シーケンシャルリードはディスクシークを最小限に抑えます。照会にすべてのローが必要でない場合でも です。 EXPLAIN Output Format題しMySQLのマニュアルページから

+0

これは別の問題です。あなたが書いている問題は小テーブルまたは高カーディナリティケースの場合です – Drew

+0

@Drew、はい、しかし可能性があります。ほとんどの場合、指定された 'WHERE'条件がレコードを返さない限り、これが理由です。 – Rahul

+0

参考のためにexample/imgurリンクを生成して、標準出力を説明に表示します。編集:ここに行く、これはあなたのケースです。http://l.imgur.com/oGc0hsw.jpg – Drew

関連する問題