我如何优化此查询?现在它在0.0100秒内执行。
SELECT comments.comment_content, comments.comment_votes, comments.comment_date,
users.user_login, users.user_level, users.user_avatar_source,
groups.group_safename
FROM comments
LEFT JOIN links ON comment_link_id=link_id
LEFT JOIN users ON comment_user_id=user_id
LEFT JOIN groups ON comment_group_id=link_group_id
WHERE comment_status='published' AND link_status='published'
ORDER BY comment_id DESC
EXPLAIN输出:
索引:
注释:
用户:
组:
答案 0 :(得分:1)
低于二十毫秒的查询时间通常被认为是慢的。正如一些人在评论中提到的那样,当你的表变大时,你需要重做优化,因为MySQL的优化器(以及其他RDMS的优化器)根据索引大小做出决策。
我建议您始终使用表名或别名限定JOIN子句中的列名。例如,您可以使用以下样式获得清晰度和可维护性:
FROM comments AS c
LEFT JOIN links AS L ON c.comment_link_id=L.link_id
LEFT JOIN users AS u ON c.comment_user_id=u.user_id
LEFT JOIN groups AS g ON c.comment_group_id=g.link_group_id
此查询选择了相当宽的表子集,因此表格越大,运行速度越慢。除非你能以某种方式缩小子集,否则这是不可避免的。
您在JOIN ... ON
操作中使用的列是否都已声明为NOT NULL
?他们应该是。
查看您使用groups
表格的方式:您已加入link_group_id
并检索group_safename
。因此,在(link_group_id,group_safename)
上尝试覆盖索引的复合词。索引至少为link_group_id
。
users
表:您已经在user_id
上找到了索引。当您的表格变大时,(user_id, user_login, user_level, user_avatar_source)
上的复合覆盖索引可能有所帮助。但这是一个低优先级的尝试。
links
表格:您正在使用link_status
和link_id
。此表的LEFT JOIN
应该是普通内部JOIN
,因为其中一列显示在WHERE
子句中。如果您的应用程序中link_status
可以是NOT NULL
,请确保以此方式声明它。然后在(link_status, link_id)
上尝试复合索引。
comments
表:就我所见,您在comment_status
上没有索引。尝试添加一个。
然后在表中放入一堆数据,为每个表运行OPTIMIZE LOCAL TABLE
,然后再次使用EXPLAIN尝试查询。