为什么MySQL只使用复合索引而不是单独的索引?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么MySQL只使用复合索引而不是单独的索引?相关的知识,希望对你有一定的参考价值。
我有下表
CREATE TABLE `test` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL
);
我需要做以下查询
SELECT * FROM `test` ORDER BY a, b LIMIT 1;
如果我添加一个复合索引
ALTER TABLE `t_test` ADD INDEX a_b(`a`, `b`);
有用
> EXPLAIN SELECT * FROM `test` ORDER BY a, b LIMIT 1;
+------+-------------+-------+-------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | test | index | NULL | a_b | 8 | NULL | 1 | |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------+
但是如果我分别添加两个索引
ALTER TABLE `t_test` ADD INDEX a(`a`), ADD INDEX b(`b`);
它失败
> EXPLAIN SELECT * FROM `test` ORDER BY a, b LIMIT 1;
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | test | ALL | NULL | NULL | NULL | NULL | 2 | Using filesort |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
即使我添加FORCE INDEX
,它也行不通。
正如我个人所理解的那样,它应该同时使用index a
和index b
,并且只比复合索引小一点。
即使我错了,它至少应该首先使用index a
然后使用filesort来排序b。
这种排序运算符真的不能使用分离的索引吗?如果是,请解释为什么它不起作用。如果不是,您是否有任何解决方案让它与单独的索引一起使用?提前致谢。
编辑
例如,我有100行。我可以先使用index a
对它们进行排序。然后在每个具有相同a
值的组中,我可以使用index b
对它们进行排序。
为什么这种方式无法在mysql上运行?
答案
当索引(复合或非复合)用于“排序”时,MySQL按顺序读取数据,并且根本不进行排序。多个索引无法做到这一点。
按顺序读取1-st索引然后进行文件排序是可能的,但它不太可能更快,所以MySQL不会这样做。
如果你真的需要这样做,你可以使用这样的子查询:
SELECT ...
FROM (
SELECT primary_key
FROM table1
ORDER BY field1
LIMIT 15
) tmp
JOIN table1 t ON t.primary_key = tmp.primary_key
ORDER BY field1, field2
当你有一个LIMIT
并且由于某种原因无法添加复合索引时,这可能很有用。
以上是关于为什么MySQL只使用复合索引而不是单独的索引?的主要内容,如果未能解决你的问题,请参考以下文章