大資料量下,分頁查詢優化方法解釋

2021-05-24 15:34:52 字數 1405 閱讀 3562

演算法如這篇文章

之前老王也發過此方法:

簡單解釋一下,也作為思路整理:

1,使用stat作為乙個單一索引

desc select id from table where stat=1 order by id limit 90000,5 ; 

|  1 | ******      | table | ref  | stat       | stat | 1      | const |    151906 | using where; using filesort |

正常執行分頁語句,通過where條件圈定了符合的資料集此時還是用到了filesort,為什麼?因為索引只對where條件過濾起到了作用,對order無效。mysql操作時的微觀應該是這樣的:

根據索引限定了結果集範圍-》取出結果集資料暫存起來-》進行排序-》輸出給客戶端。

此時就算是索引去掉了大部分資料,如果表資料基數大,剩下的資料量仍然很大,暫存結果集,並進行排序的過程仍會很長。

我們現在優化索引,將id加到stat後面形成復合索引:key `stat` (`stat`,`id`)

再次執行sql,執行的時間差不多。explain的結果如下

|  1 | ******      | sp_photo_ff | ref  | pic_stat      | pic_stat | 1       | const | 151906 | using where |

因為用到了索引進行排序,所以filesort沒了。那為什麼速度仍然不快?我認為mysql仍然按上面的流程執行的。。。所以在進行取資料和排序時的時間消耗仍然很大。

當我們最終改為兩條sql實現這個,第一條,即只根據條件和排序取出id,第二條,通過id進行準確條件查詢。第一條sql是個covering index,即並沒有真的從表中出資料,而是通過索引即完成了查詢操作,速度當然是最快的,第二條,通過主鍵進行,速度也是最快的。所以雖然是執行了兩條sql,但速度反而無可比。最早在看老王的這篇文章時,我沒能明白,現在才真弄表白了

在寫這篇博文時,要用事實說話,我發現我昨天的想法仍然有錯。昨天我認為,當取出的字段不在索引的字段範圍中時,mysql會先把where過濾的記錄暫存起來,再進行排序,因為他要保證對不同的排序此方法都適用。事實是,這個想法是錯的,上面看到了,兩種索引情況下,explain的結果中少了乙個filesort。所以mysql還是足夠聰明的,它先進行了排序,然後才暫存了記錄集。是否真的是這樣?那只能去mysql內部找答案了。

mysql大資料量分頁查詢優化

參考文章 mysql的分頁查詢十分簡單,但是當資料量大的時候一般的分頁就吃不消了。傳統分頁查詢 select c1,c2,cn from table limit n,m mysql的limit工作原理就是先讀取前面n條記錄,然後拋棄前n條,讀後面m條想要的,所以n越大,偏移量越大,效能就越差。1 盡...

mysql大資料量分頁查詢優化

參考文章 mysql的分頁查詢十分簡單,但是當資料量大的時候一般的分頁就吃不消了。傳統分頁查詢 select c1,c2,cn from table limit n,m mysql的limit工作原理就是先讀取前面n條記錄,然後拋棄前n條,讀後面m條想要的,所以n越大,偏移量越大,效能就越差。1 盡...

大資料量分頁優化

用limit offset 時並不是先跳過再查詢 而是 先查詢,再跳過 limit 100w,10 先把100w取出來,然後跳過前100w行,所以大資料分頁用limit很慢 select id,name from lx com 5000000,10 先查詢出來5000000 select id,na...