2012-11-03 52 views
2

我想知道,如果限制和偏移執行被選擇的行後:SQL如何執行限制和偏移量?

SELECT * FROM users WHERE id > 4 LIMIT 0,90 ORDER BY datetime DESC; 

這是否查詢首先選擇所有用戶的行然後應用LIMIT,還是該查詢首先將LIMIT然後選擇用戶的行?

+2

使用極限,沒有和ORDER BY意味着你不會得到預期的結果。如果你使用LIMIT,你應該確定你想要返回結果的順序。否則,MySQL不保證你將實際收到哪些行。 –

回答

2

FROM子句是在查詢中首先執行的,然後是WHERE子句。之後,應用LIMIT子句。

因此,以下是您發佈的查詢邏輯查詢處理步驟:

  • FROM條款返回的所有用戶。
  • WHERE子句應用。只有id > 4的用戶纔會轉到下一步。
  • 然後LIMIT
1

選擇查詢

SELECT * FROM users WHERE id > 4 LIMIT 0,90; 
1

http://dev.mysql.com/doc/refman/5.0/en/limit-optimization.html

如果使用LIMIT的row_count與ORDER BY,MySQL的結束,因爲它已經找到了排序結果的第一ROW_COUNT行儘快整理而不是排序整個結果。如果使用索引完成排序,則速度非常快。如果必須完成一個文件夾,那麼必須選擇與沒有LIMIT子句的查詢相匹配的所有行,並且在可以確定已找到第一個row_count行之前,必須對其中的大部分或全部進行排序。在任何一種情況下,在找到最初的行之後,不需要對結果集的任何其餘部分進行排序,而MySQL不會這樣做。

Main Reference Link

+0

MySQL從不會執行部分文件。如果它不能使用索引進行排序,它會在應用LIMIT子句之前始終對整個結果集進行排序。 –

2

所以你問並不十分有意義這裏的問題。

你真正應該問的是「MySQL是否必須查找與查詢中的WHERE子句匹配的所有行,或者它是否可以應用LIMIT並且只需要讀取至多N行?

這裏有兩種可能的情況,還有一個需要考慮的問題,以及原始查詢的問題。

  1. 如果你使用LIMIT,你應該使用ORDER BY。 MySQL沒有「自然」順序,這意味着您實際從該查詢中返回的行不是確定性的。這是一件壞事。

所以,現在你使用ORDER BY有兩種可能性。

  1. MySQL可以使用索引來滿足ORDER BY子句。在這種情況下,它可以按索引順序掃描表,尋找匹配,直到滿足LIMIT,然後停止讀取。這是有效的。

  2. MySQL 不能使用索引。然後在應用LIMIT之前,它必須找到所有可能的匹配並對整個結果集進行排序。如果行數很多,這通常很慢。

額外的事情要考慮的是,當您使用限制的偏移,MySQL就讀取所有行到起始位置之前,它會返回結果。當偏移值非常大時,這變得非常慢。

這對在MySQL高效分頁幻燈片組解釋了很多: http://www.scribd.com/doc/14683263/Efficient-Pagination-Using-MySQL

+0

你可以得到一個確定性的'LIMIT' [使用SQL:2011特性](http://www.sigmod.org/publications/sigmod-record/1203/pdfs/10.industry.zemke.pdf)。搜索'WITH TIES'。 –