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,所有数据都在一个分区上。
使用正确的 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 表达式。