2015-04-15 88 views
2

我有兩個表:posts用10k行和comments,我需要選擇換言之posts特定編號的所有comments通過posts表實現分頁,並得到所有comments上。爲此我有下一個查詢:如何提高MySQL子查詢中的LIMIT子句?

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條款通過9976 rows但不通過10行迭代如我所料:

enter image description here

同時當我運行子查詢單獨它通過10行迭代的偉大工程預期:

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

enter image description here

也有indexes on posts(post_id), comments(comment_id), comments(post_id)我不明白這個查詢有什麼問題,所以它遍歷帖子表中的所有記錄。如果有人幫我解決這個問題,我將非常感激。

+0

我相信子選擇對於外部選擇中的每個記錄都重複迭代,這就是爲什麼看起來如此之高。您可能可能重構查詢,以避免子選擇 – Vinbot

+0

可能重複[如何提高MySQL中的限制條款](http://stackoverflow.com/questions/29649131/how-to-improve-limit-clause-in-mysql ) – Siyual

+0

@Vinbot實際上我不知道如何使用不同的查詢結構實現與分頁相同的結果。你能舉個例子嗎? – Speise

回答

0

首先,你的qwuery沒有遍歷9976行。解釋顯示查詢將讀取的行數估計值(實際上,它會生成大量的執行計劃並丟棄除最低成本估計值之外的所有行)。

對於極限0,10它可以讀取少了許多行(取決於指標是如何配置的),但是當記者問到解決限制10000,10會讀了很多更

+0

但是,仍然存在一個問題 - 爲什麼MySQL估計的子​​查詢與相同的單獨查詢不同? – Speise

+0

因爲子查詢需要返回一個有序集合以進行高效查找,所以他的另一個表 – symcbean

0

9976(VS 10000)已一個改進 - 在5.6之前,「行數」通常會減少2倍。現在統計數據更準確,更穩定。

真正的答案是「EXPLAIN不夠完美」。

5.7將有一些改進。與此同時,我們陷入了諸如「10 vs 9976」之類的謎團。

當使用LIMIT時,它大部分被破壞。它在EXPLAIN EXTENDED的「已過濾」列中以另一種方式顯示。

試試EXPLAIN FORMAT=JSON ...以獲取更多信息。

與MariaDB(版本10.0?),有ANALYZE SELECT ...這將給你實際計數。它通過運行查詢,然後拋出結果集並保存統計信息來完成此操作。