Msyql優化分頁查詢
阿新 • • 發佈:2021-02-08
在使用一些常規的 SQL 時,如果我們通過一些方法和技巧來優化這些 SQL 的實現,在效能上就會比使用常規通用的實現方式更加優越,甚至可以將 SQL 語句的效能提升到另一個數量級。
1. 優化分頁查詢
通常我們是使用 <LIMIT M,N> + 合適的 order by 來實現分頁查詢,這種實現方式在沒有任何索引條件支援的情況下,需要做大量的檔案排序操作(file sort),效能將會非常得糟糕。如果有對應的索引,通常剛開始的分頁查詢效率會比較理想,但越往後,分頁查詢的效能就越差。
這是因為我們在使用 LIMIT 的時候,偏移量 M 在分頁越靠後的時候,值就越大,資料庫檢索的資料也就越多。例如 LIMIT 10000,10 這樣的查詢,資料庫需要查詢 10010 條記錄,最後返回 10 條記錄。也就是說將會有 10000 條記錄被查詢出來沒有被使用到。
我們模擬一張 10 萬數量級的 order 表,進行以下分頁查詢:
select * from `demo`.`order` order by order_no limit 10000, 20;
通過 EXPLAIN 分析可知:該查詢使用到了索引,掃描行數為 10020 行,但所用查詢時間為 0.018s,相對來說時間偏長了。
利用子查詢優化分頁查詢
以上分頁查詢的問題在於,我們查詢獲取的 10020 行資料結果都返回給我們了,我們能否先查詢出所需要的 20 行資料中的最小 ID 值,然後通過偏移量返回所需要的 20 行資料給我們呢?我們可以通過索引覆蓋掃描,使用子查詢的方式來實現分頁查詢:
select * from `demo`.`order` where id>
(select id from `demo`.`order` order by order_no limit 10000, 1)
limit 20;
通過 EXPLAIN 分析可知:子查詢遍歷索引的範圍跟上一個查詢差不多,而主查詢掃描了更多的行數,但執行時間卻減少了,只有 0.004s。這就是因為返回行數只有 20 行了,執行效率得到了明顯的提升。