平常開發中,咱們使用mysql來實現分頁功能的時候,老是會用到mysql的limit語法.而怎麼使用卻頗有講究的,今天來總結一下.mysql
limit語法支持兩個參數,offset和limit,前者表示偏移量,後者表示取前limit條數據.sql
例如:性能
## 返回符合條件的前10條語句
select * from user limit 10
## 返回符合條件的第11-20條數據
select * from user limit 10,20
複製代碼
從上面也能夠看出來,limit n
等價於limit 0,n
.學習
實際使用中咱們會發現,在分頁的後面一些頁,加載會變慢,也就是說:測試
select * from user limit 1000000,10
語句執行較慢.那麼咱們首先來測試一下.優化
首先是在offset較小的狀況下拿100條數據.(數據總量爲200左右).而後逐漸增大offset.url
select * from user limit 0,100 ---------耗時0.03s
select * from user limit 10000,100 ---------耗時0.05s
select * from user limit 100000,100 ---------耗時0.13s
select * from user limit 500000,100 ---------耗時0.23s
select * from user limit 1000000,100 ---------耗時0.50s
select * from user limit 1800000,100 ---------耗時0.98s
複製代碼
能夠看到隨着offset的增大,性能愈來愈差.spa
這是爲何呢?由於limit 10000,10
的語法其實是mysql查找到前10010條數據,以後丟棄前面的10000行,這個步驟實際上是浪費掉的.code
先找到上次分頁的最大ID,而後利用id上的索引來查詢,相似於select * from user where id>1000000 limit 100
.cdn
這樣的效率很是快,由於主鍵上是有索引的,可是這樣有個缺點,就是ID必須是連續的,而且查詢不能有where語句,由於where語句會形成過濾數據.
mysql的查詢徹底命中索引的時候,稱爲覆蓋索引,是很是快的,由於查詢只須要在索引上進行查找,以後能夠直接返回,而不用再回數據表拿數據.所以咱們能夠先查出索引的ID,而後根據Id拿數據.
select * from (select id from job limit 1000000,100) a left join job b on a.id = b.id;
複製代碼
耗時0.2秒.
用mysql作大量數據的分頁確實是有難度,可是也有一些方法能夠進行優化,須要結合業務場景多進行測試.
當用戶翻到10000頁的時候,不如咱們直接返回空好了,這麼無聊的嗎...
歡迎轉載,煩請署名並保留原文連接。
聯繫郵箱:huyanshi2580@gmail.com
更多學習筆記見我的博客------>呼延十