为什么向我的查询添加 LIMIT 会使其爬行?

Ape*_*tus 2 mysql optimization limits group-by

简单查询:

select sum(score) total,name,gender,dob,country 
from users join scores on users.id = scores.user_id
where date between '2012-01-01' and '2012-01-31 23:59:59'
group by scores.user_id having sum(score)>=1000 order by sum(score) desc limit 50
Run Code Online (Sandbox Code Playgroud)

因此,尝试获取 2012 年 1 月的累积分数列表,按分数降序排列它们并对其进行分页。

无限制:缓慢但可以:搜索 69348 行。(很高兴弄清楚如何避免临时表,但我不能)。解释说:

1, 'SIMPLE', 'scores', 'range', 'user,date,user+date', 'date', '8', '', 69348, 'Using where; Using temporary; Using filesort'
1, 'SIMPLE', 'users', 'eq_ref', 'PRIMARY', 'PRIMARY', '8', 'scores.user_id', 1, 'Using where'
Run Code Online (Sandbox Code Playgroud)

有限制:它是一样的,但行搜索现在是 1806794,它需要永远。

如果有任何区别,它是一个分区的 InnoDB,所有数据都在一个分区上。

gbn*_*gbn 5

使用正确的 ANSI group by(不是 MySQL可恶的扩展),看看会发生什么

select sum(score) total,name,gender,dob,country  
from users join scores on users.id = scores.user_id
where date between '2012-01-01' and '2012-01-31 23:59:59'
group by name,gender,dob,country
having sum(score)>=1000
order by sum(score) desc limit 50
Run Code Online (Sandbox Code Playgroud)

为什么?

MySQL 中的 GROUP BY 意味着 ORDER BY 导致这里的文件排序
将查询更改为更标准可能有助于优化器

有关 MySQL abominations扩展的更多信息:

来自关于 ORDER BY 优化的 MySQL文档

在某些情况下,MySQL 无法使用索引来解析 ORDER BY,尽管它仍然使用索引来查找与 WHERE 子句匹配的行。这些案例包括:

...

您有不同的 ORDER BY 和 GROUP BY 表达式。