如何改进MySQL子查询中的LIMIT子句?

时间:2015-04-15 15:36:49

标签: mysql sql performance subquery limit

我有两个表:posts,包含10k行和comments,我需要为特定数量的comments选择所有posts,换句话说,通过{实现分页{1}}表并获取其中的所有posts。为此,我有下一个查询:

comments

对我来说,查询的性能也非常重要。但是这个查询的select * from comments c inner join (select post_id from posts o order by post_id limit 0, 10) p on c.post_id = p.post_id; 非常奇怪,因为Explain子句遍历LIMIT而不是我预期的10行:

enter image description here

同时当我单独运行子查询时,它可以按预期迭代10行,效果很好:

9976 rows

enter image description here

explain select post_id from posts o order by post_id limit 0, 10 上还有 indexes 我不明白该查询的问题是什么,因此它会遍历帖子表中的所有记录。如果有人帮我解决这个问题,我将非常感激。

2 个答案:

答案 0 :(得分:0)

首先,你的qwuery没有迭代超过9976行。解释显示了查询将读取的行数的估计值(实际上,它会生成大量执行计划并丢弃除了成本估算最低的那个之外的所有计划。)

对于限制0,10,它可以读取更少的行(取决于索引的配置方式)但是当被要求解决限制10000时,10它会读取更多

答案 1 :(得分:0)

9976(vs 10000)已经有所改善 - 在5.6之前,“行数”通常会下降2倍。现在统计数据更准确,更稳定。

真正的答案是“EXPLAIN不完美。”

5.7将有一些改进。与此同时,我们陷入了“10 vs 9976”等神秘面纱。

当使用LIMIT时,它大部分被破坏了。它在EXPLAIN EXTENDED的“已过滤”列中以另一种方式显示。

尝试EXPLAIN FORMAT=JSON ...以获取更多信息。

使用MariaDB(版本10.0?),ANALYZE SELECT ...会为您提供实际计数。它通过运行查询,然后抛出结果集并保留统计信息来完成此操作。