MySQL--limit使用注意


limit m,n 的意義是在選擇、查詢得到的結果中,從第m條開始,拿連續的n條作為結果返回。根據它的原理可以知道,select ....limit m,n時要掃描得到的數據條數是m+n條。這就導致m特別大的時候,select執行完成會花費很多時間。但是limit大都數情況下又是必須要用的,因為limit可以讓數據庫只返回服務器真正需要的數據條數,減少了網絡中傳輸的開銷。現在有表table1:

  id          value      type

-------------------------------------

  1          100           0

       2          2009         1

    .....         ......            ....

id為遞增主鍵,value建立了索引。這個表有幾百萬的數據,現在執行sql: 

select * from table1 where value = 100 limit 300000,10

上述sql很簡單,人肉解析: 從為value建立的索引上找到300010條value=100的記錄的id,再拿這300010個id去主鍵索引找到對應的葉子結點,拿到每個id對應的數據返回。這種方式下,sql的執行非常耗時。

解決辦法1,使用索引覆蓋得到含300010條數據的子表,與原表做連接,再select:

select * from table1 A inner join (
    select id from table1 where value = 100 limit 300000,10
) as B
on A.id = B.id

變化就是 select id from table1 where value = 100 limit 300000,10  在value的索引上查詢時只是把id查出來,由於這個索引上本來就有id,因此這時用到了索引覆蓋,速度非常快。在得到300010個id的后10個后,與原表用id做一個連接,再select * 即可完成原有的功能,速度非常快。

解決辦法2:有些情況可以 使用 limit n 代替 limit m,n

如果條件允許,即我們知道下一次查詢第一條數據的篩選條件,那就應該使用這個條件使得:where查出的數據第一條就是我們需要的,只需從第一條連續取n條即可:

select id from table1 where value = 100 and id > xxx and xxx .... limit 10

當然,上面的方法雖然是執行速度特別快,但只是在我們知道下一條數據的條件時才能做到。

 

總結就是:

 1. 如果limit m, n時 m 特別大,select 的列又沒能用上索引覆蓋,就可以考慮先select某個列以用上索引覆蓋並把結果作為一個子表,再用原表與子表做連接,最后select出所有列。

 2. 如果我們知道下一條我們需要的數據的查詢條件,就可以考慮用where語句時用上這個條件,然后使用 limit n 從第一條取連續的 n 條,避免查詢大量的無效行。

歸根結底就是:減少MySQL 從磁盤讀取數據頁的數量,InnoDB每個頁一般16KB。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM