首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么MySQL只使用复合索引而不使用单独的索引?

为什么MySQL只使用复合索引而不使用单独的索引?
EN

Stack Overflow用户
提问于 2019-01-17 15:36:53
回答 1查看 45关注 0票数 1

我有下面的表格

代码语言:javascript
复制
CREATE TABLE `test` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL
);

我需要做下面的查询

代码语言:javascript
复制
SELECT * FROM `test` ORDER BY a, b LIMIT 1;

如果我添加一个综合索引

代码语言:javascript
复制
ALTER TABLE `t_test` ADD INDEX a_b(`a`, `b`);

它起作用了

代码语言:javascript
复制
> 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 |       |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------+

但是如果我分别添加两个索引

代码语言:javascript
复制
ALTER TABLE `t_test` ADD INDEX a(`a`), ADD INDEX b(`b`);

它失败了

代码语言:javascript
复制
> 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 aindex b,并且只比综合指数小一点。

即使我错了,它至少应该先使用index a,然后再使用filesort对b进行排序。

这个排序操作符真的不能使用分隔索引吗?如果是,请解释为什么它不工作。如果没有,您有什么解决方案可以让它与单独的索引一起工作吗?提前谢谢。

编辑

例如,我有100行代码。我可以先使用index a对它们进行排序。然后在每个具有相同a值的组中,我可以使用index b对它们进行排序。

为什么这种方式不能在MySQL上工作?

EN

回答 1

Stack Overflow用户

发布于 2019-01-17 16:31:31

当索引(复合索引或非索引索引)用于“排序”时,MySQL将按顺序读取数据,而根本不进行排序。对于多个索引,这是不可能的。

在第一个索引上按顺序读取,然后进行文件排序是可能的,但它不太可能更快,所以MySQL不会这样做。

如果您确实需要这样做,您可以使用如下所示的子查询:

代码语言:javascript
复制
    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,但由于某些原因不能添加复合索引时,这会很有用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54231067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档