Mysql 不使用 group by 和 order by 索引

标签 mysql performance optimization indexing

我有带有以下列的表用户。

ID、名称、更新时间

带有解释计划的查询

mysql> explain select * from users group by users.id order by users.updated_at desc limit 10;
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
| id | select_type | table       | type | possible_keys | key  | key_len | ref  | rows   | Extra          |
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
|  1 | SIMPLE      | users | ALL  | NULL          | NULL | NULL    | NULL | 190551 | Using filesort |
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
1 row in set (0.00 sec)

创建了一个新索引

create index test_id_updated_at on users (id, updated_at);

创建新索引后,仍然通过解释计划获得相同的结果。

mysql> explain select * from users group by users.id order by users.updated_at desc limit 10;
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
| id | select_type | table       | type | possible_keys | key  | key_len | ref  | rows   | Extra          |
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
|  1 | SIMPLE      | users | ALL  | NULL          | NULL | NULL    | NULL | 190551 | Using filesort |
+----+-------------+-------------+------+---------------+------+---------+------+--------+----------------+
1 row in set (0.00 sec)

在查询中强制使用新索引后,仍然得到相同的结果。

我不明白为什么在创建新索引后显示“使用文件排序”。

最佳答案

我复制了你的场景,mysql使用了索引:

mysql> explain SELECT * FROM test_index GROUP BY id ORDER BY updated_at DESC;
+----+-------------+------------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows   | Extra                           |
+----+-------------+------------+------+---------------+------+---------+------+--------+---------------------------------+
|  1 | SIMPLE      | test_index | ALL  | NULL          | NULL | NULL    | NULL | 393520 | Using temporary; Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+--------+---------------------------------+
1 row in set (0.00 sec)

mysql> CREATE INDEX index1 ON test_index(id, updated_at);
Query OK, 0 rows affected (1.85 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain SELECT * FROM test_index GROUP BY id ORDER BY updated_at DESC;
+----+-------------+------------+-------+---------------+--------+---------+------+--------+---------------------------------+
| id | select_type | table      | type  | possible_keys | key    | key_len | ref  | rows   | Extra                           |
+----+-------------+------------+-------+---------------+--------+---------+------+--------+---------------------------------+
|  1 | SIMPLE      | test_index | index | NULL          | index1 | 12      | NULL | 393520 | Using temporary; Using filesort |
+----+-------------+------------+-------+---------------+--------+---------+------+--------+---------------------------------+
1 row in set (0.00 sec)

也许你的mysql版本?在 5.5 上测试过。

如果不知道完整的表结构以及您想要用此检索的内容(指定字段而不是“*”),则很难优化此查询(删除 using filesort 和临时)

关于Mysql 不使用 group by 和 order by 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23636027/

相关文章:

performance - 要使事务性内存可行,需要什么条件?

performance - 将fpu切换为单精度

optimization - 我应该使用尽可能小的类型吗?

php - 如何为数据库中的用户和管理员建模?

performance - 多模式对象设计DS

performance - Perl 的统计数据有更快的替代方案吗?

python - 我可以相信 R 中 `nloptr` 的结果吗?

php - 名称-值和键-值对均在 PHP 文件中创建(用于 json 编码)

PHP MySQL While 循环 多个表

mysql - (Mysql中小数乘法的精度和小数位数