in
クエリはインデックスを使用しないため、mysqlはすべてのレコードをスキャンして行を検索します。
http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.htmlから
Bツリーインデックスの特性
Bツリーインデックスは、=、>、> =、<、<=、またはBETWEEN演算子を使用する式の列比較に使用できます。
ありませんIN
と
ハッシュインデックスの特性
ハッシュインデックスには、今説明したものとは多少異なる特性があります。
これらは、=または<=>演算子を使用する等式比較にのみ使用されます(ただし、非常に高速です)。これらは、値の範囲を見つける<などの比較演算子には使用されません。
どちらもありませんIN
。
@tombomが述べたように、のfoo IN ('bar', 'bla')
略ですfoo = 'bar' OR foo = 'bla'
が、私はそれらが異なっていると信じています。そこで、十分なデータレコードがあるテーブルでテストを行い、次のことを確認します。
mysql> show columns from t_key;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| a | int(11) | NO | PRI | NULL | auto_increment |
| b | int(11) | YES | MUL | NULL | |
+-------+---------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> select count(a) from t_key;
+----------+
| count(a) |
+----------+
| 989901 |
+----------+
1 row in set (0.00 sec)
mysql> explain select a from t_key where a in (select max(a) from t_key);
+----+--------------------+-------+-------+---------------+---------+---------+------+--------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-------+---------------+---------+---------+------+--------+------------------------------+
| 1 | PRIMARY | t_key | index | NULL | PRIMARY | 4 | NULL | 989901 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+--------------------+-------+-------+---------------+---------+---------+------+--------+------------------------------+
2 rows in set (0.00 sec)
mysql> explain select a from t_key where a =(select max(a) from t_key);
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
| 1 | PRIMARY | t_key | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
| 2 | SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
2 rows in set (0.00 sec)
次にIN
、静的シーケンスを使用してクエリを試します。これは、@tombomが述べたように機能します。
mysql> explain select a from t_key where a in (100,200);
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | t_key | range | PRIMARY | PRIMARY | 4 | NULL | 2 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
mysql> explain select a from t_key where a=100 or a=200;
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | t_key | range | PRIMARY | PRIMARY | 4 | NULL | 2 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
IN
可能な場合にmysqlがクエリを1つに変換するかどうかはわかりませんORs
(たとえば、シーケンスはクエリの前にわかっています)。関連するドキュメントは見つかりませんでしたがexplain
、この状況でテーブルをスキャンしたことが示されています。