我有一个测试表 (table1),其中有 6 条记录。我想根据列 (col1) 获取多个值的数据。 所以我索引了该列。现在,如果我在 IN 子句中传递多个值,选择具有强制索引的所有列 (*),我将获得特定记录而不是全表扫描。如果我对选定的列运行相同的查询,我会看到它执行全表扫描。
我读到在 select 查询中使用 select all (*) 是不好的。但是这里如果我不使用全选 (*) 将会进行全表扫描。 我无法理解 mysql 如何读取查询。请帮我解决这个问题。
表格
+----+--------+---------+
| id | col1 | col2 |
+----+--------+---------+
| 1 | 100000 | E100000 |
| 2 | 100001 | E200001 |
| 3 | 100002 | E300002 |
| 4 | 100003 | E400003 |
| 5 | 100004 | E500004 |
| 6 | 100005 | E600005 |
+----+--------+---------+
索引
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| 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(使用 FORCE INDEX (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(使用 FORCE INDEX (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 |
+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+
最佳答案
- MySQL 优化器发现表太小,将全盘扫描 比先搜索索引然后再检索数据更有效。
- 当你只选择一列时,MySQL 优化器会发现,这 列在索引中,不需要从中检索数据 表格 - 阅读索引就足够了。
优化器如何确定什么更有效? 它试图预测磁盘读取 block 操作的数量。
正如之前在评论中提到的,在大表上 EXPLAIN 会有所不同。
关于Mysql IN子句全表扫描,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19141365/