MySQL在解释语句中声明它时不会使用我的索引

问题描述 投票:0回答:1

我最近遇到了涉及MySQL DBSM的问题。 表格如下:

 CREATE TABLE `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(60) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` enum('男','女') DEFAULT NULL,
`amount` float(10,2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_i` (`name`),
KEY `sex` (`sex`)
) ENGINE=InnoDB AUTO_INCREMENT=5000001 DEFAULT CHARSET=utf8 

如上所示,我在col name上创建了一个colume索引 我想在name上执行范围查询,解释声明是

mysql> explain select * from orders where name like '王%';
+----+-------------+--------+------------+-------+---------------+--------+---------+------+-------+----------+----------------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key    | key_len | ref  | rows  | filtered | Extra                            |
+----+-------------+--------+------------+-------+---------------+--------+---------+------+-------+----------+----------------------------------+
|  1 | SIMPLE      | orders | NULL       | range | name_i        | name_i | 183     | NULL | 20630 |   100.00 | Using index condition; Using MRR |
+----+-------------+--------+------------+-------+---------------+--------+---------+------+-------+----------+----------------------------------+
1 row in set, 1 warning (0.10 sec)

所以它应该使用索引name_i并在一瞬间完成查询(我的同学花了0.07秒)但是,结果如下:

| 4998119 | 王缝   |   27 | 男   | 159.21 |
| 4998232 | 王求葬 |   19 | 男   | 335.65 |
| 4998397 | 王倘予 |   49 | 女   | 103.39 |
| 4998482 | 王厚   |   77 | 男   | 960.69 |
| 4998703 | 王啄淋 |   73 | 女   | 458.85 |
| 4999106 | 王般埋 |   70 | 女   | 700.98 |
| 4999359 | 王胆具 |   31 | 女   | 362.83 |
| 4999510 | 王铁脾 |   31 | 女   | 973.09 |
| 4999880 | 王战万 |   59 | 女   | 127.28 |
| 4999928 | 王忆   |   42 | 女   |  72.47 |
+---------+--------+------+------+--------+
11160 rows in set (3.43 sec)

并且它似乎根本不使用索引,因为数据按主键id而不是col name排序(除了它太慢,与0.07秒相比)。

有没有人遇到过这个问题?

mysql performance indexing
1个回答
1
投票
  • “Kings”(王)表的百分比是多少?如果它超过20%,它将选择进行表扫描而不是使用索引。 (这可能实际上更快。)(根据评论,表中有0.22%是国王。)
  • EXPLAIN和查询的执行是分开的事情。虽然我不记得证明这一点,但EXPLAIN可能会说一件事,但查询会以另一种方式工作。
  • 你表中有500万行吗?当你第一次运行缓存时,缓存是否“冷”?它必须从磁盘中获取11,160行?然后第二次,所有都在缓存中,速度更快?
  • 表格是按字母顺序加载的(或者是中文单词的顺序)命令?如果是这样,ids和名称很可能在同一个顺序中?
  • 显然你正在使用utf8_general_ci COLLATION?也许它不能很好地排序中国人。 (提供一个测试用例;我会做一些测试。)
  • 我不明白为什么它提到MRR
  • 我也被“1分32.24秒”困惑了。 ORDER BY name应该进一步鼓励优化器使用INDEX(name)。你能打开“优化器跟踪”吗?

要真正了解它是否使用了索引,请执行以下操作:

FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handler%';

如果大数字看起来像表中的行数,那么它会进行表扫描。如果他们看起来更像11160,那么他们使用索引。

© www.soinside.com 2019 - 2024. All rights reserved.