Mysql 导致大规模减速的排序
我正在开发一个评论系统,我问了另一个问题。模式基本相同,只是我在Mysql 导致大规模减速的排序,mysql,Mysql,我正在开发一个评论系统,我问了另一个问题。模式基本相同,只是我在comments表中添加了一个rating列,并设置了一个触发器,在comments\u ratings表中发生更改时更新它,以避免每次需要获取评论时都计算评级 因此,当我执行查询以获取最新评论时: SELECT c.*, COALESCE (COUNT(r.id), 0) AS replies FROM ( SELECT ... FROM
comments
表中添加了一个rating
列,并设置了一个触发器,在comments\u ratings
表中发生更改时更新它,以避免每次需要获取评论时都计算评级
因此,当我执行查询以获取最新评论时:
SELECT
c.*, COALESCE (COUNT(r.id), 0) AS replies
FROM
(
SELECT
...
FROM
comments c
LEFT JOIN users u ON u.id = c.author
LEFT JOIN comments_ratings crv ON crv.COMMENT = c.id
AND crv.USER = ?
WHERE
c.item = ?
AND c.type = ?
ORDER BY
c.id DESC
LIMIT 0,
10
) AS c
LEFT JOIN comments r ON c.id = r.reply
GROUP BY
c.id
ORDER BY
c.id DESC
我在大约0.001~0.003秒的时间内得到一个结果,我可以确认缓存对我没有帮助,因为我尝试了用随机值限制,并且时间总是在这个范围内
但是,如果我尝试按评级
而不是c.id
排序,则查询需要30秒以上的时间(我有很多测试数据)。当我打开探查器时,我看到它90%以上的时间都用于复制到tmp表
。我假设它正在将整个表复制到内存表中并在其中排序,但我不明白为什么会发生这种情况,因为我已经在列rating
上创建了一个索引,这应该有帮助吗
我打破数据库规范化并创建rating
列(而不是计算列)的原因是为了能够对其进行索引以简化排序
在这一点上我很困惑,你知道我做错了什么吗?当你说:“我试着按评级而不是c.id排序”,你是指内部选择还是外部选择?@Renzo内部选择,外部只对少量记录进行排序,所以它不影响,实际上ymysql使用一组条件按索引进行排序。对于内部查询,
explain
的输出是什么?@AleksandrK。我将在几个小时后用解释输出更新问题,因为我现在无法访问我的开发服务器。假设
:您的id
列和评级
列上有索引Fact
:MySQL不能在不同的WHERE/ORDER BY/GROUP BY
子句的上下文中使用多个索引(罕见的索引合并情况除外,这不是您的情况)。它决定使用id
索引进行分组。因此,当按另一列排序时,查询将调用非索引排序的MySQL机制,这将导致文件排序,并进一步复制到临时存储