简体   繁体   English

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

[英]How to improve LIMIT clause in MySQL subquery?

I have two tables : posts with 10k rows and comments and I need to select all comments for particular numbers of posts in other words implement the pagination by posts table and get all comments thereof. 我有两个表:具有1万行和comments posts ,我需要针对特定​​数量的posts选择所有comments ,换句话说,通过posts表实现分页并获取所有comments For that purpose I have the next query: 为此,我有下一个查询:

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;

Also it is very important for me the performance of query. 对于我来说,查询的性能也很重要。 But the Explain of this query is very strange because LIMIT clause iterate through 9976 rows but not through 10 rows as I expect: 但是此查询的Explain很奇怪,因为LIMIT子句遍历了9976 rows而不是我期望的10行:

在此处输入图片说明

At the same time when I run subquery separately it works great with iterating through 10 rows as expected: 同时,当我分别运行子查询时,它可以按预期迭代10行,效果很好:

explain select post_id from posts o order by post_id  limit 0, 10

在此处输入图片说明

Also there is indexes on posts(post_id), comments(comment_id), comments(post_id) . posts(post_id), comments(comment_id), comments(post_id)上也有indexes I don't understand what is the problem with that query so it iterate through all records in posts table . 我不明白该查询的问题是什么,所以它遍历posts表中的所有记录 I will be very thankful if somebody help me with that issue. 如果有人帮助我解决这个问题,我将非常感激。

Firstly, your qwuery did not iterate over 9976 rows. 首先,您的qwuery没有遍历9976行。 Explain shows an estimate of the number of rows the query will read (actually, it generates lots of execution plans and discards all but the one with the lowest cost estimate). 说明显示了查询将要读取的行数的估计值(实际上,它会生成许多执行计划,并丢弃除成本估计最低的行之外的所有执行计划)。

For limit 0,10 it may read much fewer rows (depending on how the indexes are configured) but when asked to resolve limit 10000, 10 it will read a lot more 对于限制0,10,它读取的行可能少得多(取决于索引的配置方式),但是当要求解析限制10000(10)时,它将读取更多的行

9976 (vs 10000) is already an improvement -- before 5.6, "Rows" was often off by as much as a factor of 2. Now the statistics are more accurate, and more stable. 9976(相对于10000)已经有了改进-在5.6之前,“行”的偏差通常是2的倍。现在,统计信息更加准确和稳定。

The real answer is " EXPLAIN is less than perfect." 真正的答案是“解释EXPLAIN完美”。

5.7 will have some improvements. 5.7将有一些改进。 Meanwhile, we are stuck with mysteries like "10 vs 9976". 同时,我们陷入了“ 10 vs 9976”之类的谜团。

It is mostly broken when LIMIT is used. 使用LIMIT时,它通常会损坏。 It manifests in another way in the "Filtered" column of EXPLAIN EXTENDED . 它以另一种方式显示在EXPLAIN EXTENDED的“已过滤”列中。

Try out EXPLAIN FORMAT=JSON ... to get a little more information. 试用EXPLAIN FORMAT=JSON ...以获取更多信息。

With MariaDB (version 10.0?), there is ANALYZE SELECT ... which will give you actual counts. 对于MariaDB(10.0版?),有ANALYZE SELECT ...可以为您提供实际计数。 It does this by running the query, then tossing the resultset and keeping the statistics. 它通过运行查询,然后扔结果集并保留统计信息来做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM