5

我有一个包含 6 条记录的测试表(table1)。我想根据列(col1)获取多个值的数据。所以我索引了该列。现在,如果我在 IN 子句中传递多个值,选择具有强制索引的所有列(*),我会得到特定的记录而不是全表扫描。如果我对选定的列运行相同的查询,我会看到它会进行全表扫描。

我读过在选择查询中使用全选(*)并不好。但是在这里,如果我不使用全选 (*),则会进行全表扫描。我无法理解 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      |         |               |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

解释(使用强制索引(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 |
+----+-------------+----------+-------+---------------+-------+---------+------+------+-------------+

解释(使用强制索引(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 |
+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+
4

1 回答 1

5
  1. MySQL优化器发现表太小,全扫描比先搜索索引再检索数据效率更高。
  2. 当您只选择一列时,MySQL 优化器会看到该列在索引中,并且不需要从表中检索数据 - 读取索引就足够了。

优化器如何确定什么更有效?它试图预测磁盘读取块操作的数量。

正如之前在评论中提到的那样,在大桌子上 EXPLAIN 会有所不同。

于 2013-10-02T18:31:27.330 回答