简体   繁体   English

MySQL IN子句全表扫描

[英]Mysql IN clause full table scan

I have a test table (table1) with 6 records in it. 我有一个测试表(table1),其中有6条记录。 I wanted to fetch data based on column (col1) for multiple values. 我想基于列(col1)获取多个值的数据。 So i indexed the column. 所以我索引了列。 Now if i pass multiple values in IN clause selecting all columns(*) with forced index, i get particular records instead of full table scan. 现在,如果我在IN子句中传递多个值以选择具有强制索引的所有column(*),则将获得特定记录,而不是全表扫描。 If i run same query with selected column i see that it does full table scan. 如果我对选定的列运行相同的查询,我会看到它进行了全表扫描。

I have read that using select all (*) in select query is not good. 我已经读过,在选择查询中使用全选(*)不好。 But here if i don't use select all (*) there will be a full table scan. 但是在这里,如果我不使用全选(*),将进行全表扫描。 I'm not able to understand how mysql reads the query. 我不明白mysql如何读取查询。 Please help me to sort out this issue. 请帮助我解决此问题。

TABLE

+----+--------+---------+
| id | col1   | col2    |
+----+--------+---------+
|  1 | 100000 | E100000 |
|  2 | 100001 | E200001 |
|  3 | 100002 | E300002 |
|  4 | 100003 | E400003 |
|  5 | 100004 | E500004 |
|  6 | 100005 | E600005 |
+----+--------+---------+

INDEX 指数

+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| table1   |          0 | PRIMARY  |            1 | id          | A         |           6 |     NULL | NULL   |      | BTREE      |         |               |
| table1   |          1 | col1     |            1 | col1        | A         |           6 |     NULL | NULL   |      | BTREE      |         |               |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

EXPLAIN (USING FORCE INDEX (col1) AND selecting all(*) columns) 解释(使用力索引(col1)并选择所有(*)列)

select * from table1 force index(col1) where col1 in ('100000', '100001');

+----+-------------+----------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table    | type  | possible_keys | key   | key_len | ref  | rows | Extra       |
+----+-------------+----------+-------+---------------+-------+---------+------+------+-------------+
|  1 | SIMPLE      | table1   | range | col1          | col1  | 10      | NULL |    2 | Using where |
+----+-------------+----------+-------+---------------+-------+---------+------+------+-------------+

EXPLAIN (USING FORCE INDEX (col1) AND selecting only 1 column data instead of all(*)) 解释(使用力索引(col1)并仅选择1列数据而不是全部(*))

select col1 from table1 force index(col1) where col1 in ('100000', '100001');

+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table    | type  | possible_keys | key   | key_len | ref  | rows | Extra                    |
+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+
|  1 | SIMPLE      | table1   | range | col1          | col1  | 10      | NULL |    6 | Using where; Using index |
+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+
  1. MySQL optimizer sees that the table is too small and full scan will be more efficient than searching an index first and retrieving data later. MySQL优化器发现表太小,与先搜索索引然后再检索数据相比,全扫描将更有效。
  2. When you select only one column, MySQL optimizer sees, that this column is in the index, and it is not necessary to retrieve data from the table - reading the index is enough. 当您只选择一个列时,MySQL优化器会看到该列在索引中,并且不需要从表中检索数据-读取索引就足够了。

How optimizer determine what is more efficient? 优化器如何确定更有效的方法? It tries to predict quantity of disk read-block operations. 它尝试预测磁盘读取块操作的数量。

As it was mentioned before in comments, on big table EXPLAIN would be different. 正如之前在评论中提到的,在大桌子上EXPLAIN会有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM