消極式載入解決offset過大導致的分頁效能問題

來源:互聯網
上載者:User

當我們展示一個列表中的內容時,難免會遇到分頁問題,因為列表中的內容數量可能很多,但是使用者能一次看到的介面大小是有限的,不可能一個介面展示所有的內容,從後端一次性取太多的資料也會給後端造成額外的壓力。

一般來說,儲存在Mysql中的資料我們有兩種分頁方式:基於id的分頁和基於offset的分頁。

下面以我在實際生產環境中遇到的一個sql為例,相關欄位因為保密問題均用A、B、C……代替。

SELECT  *FROM  table_A USE INDEX (index_A)WHERE  A = xxx  AND B = xxx  AND C IN (xxx)ORDER BY  D DESCLIMIT  33380, 11KEY `index_A` (`A`,`B`,`D`,`C`)

mysql使用offset分頁的時候會首先去二級索引(index_A)中找出滿足條件的offset+limit行記錄的id,然後根據id去聚簇索引中找到對應的行記錄,取出offset+limit行資料,最後丟掉offset行,只保留limit行,這樣效率在offset很大的時候很差,因為去聚簇索引中訪問了太多不必要的資料。

上面這個語句的執行時間大概是8s,而id分頁和上面有什麼不同呢。id分頁就是每次去後端請求資料時,帶上前一頁最後一個id,這樣的話我們在去mysql撈資料的時候where條件裡加上一個id>last_id,limit 33380, 11換成limit 11,按照id來order_by。這樣可以少去聚簇索引中拿很多資料。上面的例子就可以少拿3w多條,只拿需要的11條。

id分頁的限制。
id分頁往往需要在產品上做一些妥協,因為如果每次拿資料都是基於上一頁最後一個id的話,我們就無法進行指定頁的跳轉,例如直接跳到第5頁等等,載入資料的時候使用的是更多按鈕。

如果上述sql所在服務改成id分頁的話需要改產品分頁設計,前端可能也要調整,改動會大一點。有一種消極式載入的方式,可以解決offset過大導致的分頁效能問題。

我們將上述例子中的sql拆成兩句:

1.SELECT  table_A.idFROM  table_A USE INDEX (index_A)WHERE  A = xxx  AND B = xxx  AND C IN (xxx)ORDER BY  D DESCLIMIT  33380, 11;2.Select * from table_A where id in (ids)

兩個查詢加起來時間大概50ms,相比之前的8s,快了很多,原因如下:

第一個查詢會走覆蓋索引,因為所有查詢的列都在二級索引(index_A)中,不用去訪問聚簇索引中的資料行,這樣效率是很快的,我們可以拿到我們需要的11個記錄的id,之後第二個sql根據id去聚簇索引中拿資料也很快。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.