首先看一下分頁的基本原理:
復(fù)制代碼 代碼如下:
mysql> explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20G ***************** 1. row ************** id: 1 select_type: SIMPLE table: message type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 10020 Extra: 1 row in set (0.00 sec)
文中提到一種”clue”的做法,給翻頁提供一些”線索”,比如還是SELECT * FROM message ORDER BY id DESC,按id降序分頁,每頁20條,當(dāng)前是第10頁,當(dāng)前頁條目id最大的是9527,最小的是9500,如果我們只提供”上一頁”、”下一頁”這樣的跳轉(zhuǎn)(不提供到第N頁的跳轉(zhuǎn)),那么在處理”上一頁”的時(shí)候SQL語句可以是:
復(fù)制代碼 代碼如下:
SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20;
處理”下一頁”的時(shí)候SQL語句可以是:
復(fù)制代碼 代碼如下:
SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 20;
缺點(diǎn)是只能提供”上一頁”、”下一頁”的鏈接形式,但是我們的產(chǎn)品經(jīng)理非常喜歡”<上一頁 1 2 3 4 5 6 7 8 9 下一頁>”這樣的鏈接方式,怎么辦呢?
如果LIMIT m,n不可避免的話,要優(yōu)化效率,只有盡可能的讓m小一下,我們擴(kuò)展前面的”clue”做法,還是SELECT * FROM message ORDER BY id DESC,按id降序分頁,每頁20條,當(dāng)前是第10頁,當(dāng)前頁條目id最大的是9527,最小的是9500,比如要跳到第8頁,我看的SQL語句可以這樣寫:
復(fù)制代碼 代碼如下:
SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20,20;
復(fù)制代碼 代碼如下:
SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 40,20;
注意SQL語句里面的ASC和DESC,如果是ASC取出來的結(jié)果,顯示的時(shí)候記得倒置一下。
已在60W數(shù)據(jù)總量的表中測(cè)試,效果非常明顯。
新聞熱點(diǎn)
疑難解答
圖片精選