參考文章:https://www.dexcoder.com/selfly/article/293mysql
Mysql的分頁查詢十分簡單,可是當數據量大的時候通常的分頁就吃不消了。sql
傳統分頁查詢:SELECT c1,c2,cn… FROM table LIMIT n,mxcode
MySQL的limit工做原理就是先讀取前面n條記錄,而後拋棄前n條,讀後面m條想要的,因此n越大,偏移量越大,性能就越差。性能
推薦分頁查詢方法:測試
一、儘可能給出查詢的大體範圍優化
SELECT c1,c2,cn... FROM table WHERE id>=20000 LIMIT 10;
二、子查詢法spa
SELECT c1,c2,cn... FROM table WHERE id>= ( SELECT id FROM table LIMIT 20000,1 ) LIMIT 10;
三、高性能MySQL一書中提到的只讀索引方法code
通常表中常常做爲條件查詢的列都會創建索引,例如以下查詢blog
SELECT id, content FROM tb_chat ORDER BY create_time DESC LIMIT 24000, 20;
SELECT id, content FROM tb_chat INNER JOIN ( SELECT id FROM tb_chat ORDER BY create_time LIMIT 24000, 20 ) AS page USING(id);
這樣當前查詢頁的內容就只會在索引中進行,當獲得當前頁的id再統一經過一個INNER JOIN獲得最終要獲得的數據詳情,避免了對大量數據詳情進行操做的消耗。固然JOIN操做也能夠經過子查詢實現,不過書中介紹5.6以前版本的mysql相比子查詢仍是優先使用JOIN。索引
對上一個sql繼續優化改進,當有查詢條件分頁時,必定要確保有數據是在limit後面的條件裏,正常有輸入條件檢索查詢應該是limit 0, 10 我寫的是limit 15000,20只是爲了測試,由於符合該條件的數據只有1萬5千多個,否則超出這個數就查不到數據了,切記。
SELECT id, content,c.z_type FROM tb_chat c INNER JOIN ( SELECT id,z_type FROM tb_chat WHERE z_type='1' ORDER BY create_time LIMIT 15000, 20 ) AS page USING(id);
等同於:
SELECT c.id, c.content,c.z_type FROM tb_chat c INNER JOIN ( SELECT id,z_type FROM tb_chat WHERE z_type='1' ORDER BY create_time LIMIT 15000, 20 ) AS p ON c.id=p.id;
我的以爲此方法更爲通用,並且通過個人測試,發現表中總數據只有3萬條數據時兩個sql語句的執行時間居然相差4倍,優化前的sql執行須要120ms,而優化後的sql須要30ms。
四、第一步用用程序讀取出ID,而後再用IN方法讀取所需記錄
程序讀ID:
SELECT id FROM table LIMIT 20000, 10; SELECT c1, c2, cn .. . FROM table WHERE id IN (id1, id2, idn.. .)