mysql分页limit运算,MySQL的limit分页查询及性能问题
MySQL 通過 limit 實現分頁查詢。limit 接收一個或兩個整數型參數。如果是兩個參數,第一個指定返回記錄行的偏移量,第二個指定返回記錄行的最大數目。初始記錄行的偏移量是 0。為了與 PostgreSQL 兼容,limit 也支持limit a offset b【a:取的記錄數;b:索引】。
一、分頁查詢
客戶端通過傳遞 start(頁碼),pageSize(每頁顯示的條數)兩個參數去分頁查詢數據庫表中的數據。MySql 數據庫提供的分頁函數 limit m,n 用法和實際需求不切合,所以就需要根據實際情況去改寫適合分頁的語句。
1??查詢第1條到第10條的數據select * from table limit 0,10;
--->對應需求就是查詢第一頁的數據:select * from table limit (1-1)*10,10;
2??查詢第11條到第20條的數據select * from table limit 10,10;
--->對應需求就是查詢第二頁的數據:select * from table limit (2-1)*10,10;
3??查詢第21條到第30條的數據select * from table limit 20,10;
--->對應需求就是查詢第三頁的數據:select * from table limit (3-1)*10,10;
由此,得出符合需求的分頁 sql 格式是:select * from table limit (start-1)*pageSize,pageSize;其中 start 是頁碼,pageSize 是每頁顯示的條數。
二、性能問題
對于小的偏移量,直接用 limit 查詢沒有什么問題。隨著數據量的增大,越往后分頁,limit 語句的偏移量越大,速度也會明顯變慢。
優(yōu)化思想:
避免數據量大時掃描過多的記錄
解決:
子查詢的分頁方式或者 JOIN 分頁方式。JOIN 分頁和子查詢分頁的效率基本在一個等級上,消耗的時間也基本一致。
一般 MySQL 的主鍵是自增的數字類型,這種情況下可以使用下面的方式進行優(yōu)化。以真實的生產環(huán)境的6萬條數據的一張表為例,比較一下優(yōu)化前后的查詢耗時:
-- 傳統(tǒng) limit,文件掃描
select * from table order by id limit 50000,2;
受影響的行: 0
時間: 0.171s
-- 子查詢方式,索引掃描
select * from table
where id >= (select id from table order by id limit 50000 , 1)
limit 2;
受影響的行: 0
時間: 0.035s
-- JOIN 分頁方式
select * from table as t1
join (select id from table order by id limit 50000, 1) as t2
where t1.id <= t2.id order by t1.id limit 2;
受影響的行: 0
時間: 0.036s
可以看到經過優(yōu)化性能提高了很多倍。
優(yōu)化原理:
子查詢是在索引上完成的,而普通的查詢是在數據文件上完成的。通常來說,索引文件要比數據文件小得多,所以操作起來也會更有效率。因為要取出所有字段內容,普通查詢需要跨越大量數據塊并取出,而另一種方式直接根據索引字段定位后,才取出相應內容,效率自然大大提升。因此,對 limit 的優(yōu)化,是避免直接使用 limit,而是首先獲取到 offset 的 id,然后直接使用 limit size 來獲取數據。
在實際項目使用,可以利用類似策略模式的方式去處理分頁。例如,每頁 100 條數據,判斷如果是 100 頁以內,就使用最基本的分頁方式;如果大于 100,則使用子查詢的分頁方式。
三、limit 優(yōu)化。使用合理的分頁方式以提高分頁的效率
使用 limit 實現分頁邏輯。不僅提高了性能,同時減少了不必要的數據庫和應用間的網絡傳輸。
查詢結果只有一條或者只要最大/最小一條記錄,建議用 limit 1。這是為了使 explain 中 type 列達到 const 類型。“l(fā)imit 1”可以避免全表掃面,只要找到了對應的一條記錄,就不會繼續(xù)向下掃描了,效率將會大大提高。當然,如果查詢字段是唯一索引的話,沒必要加 limit 1,因為 limit 的存在主要就是為了防止全表掃描,從而提高性能,如果一個語句本身可以預知不用全表掃描,有沒有 limit ,性能的差別并不大。
使用下面 SQL 語句做分頁的時候,隨著表數據量的增加,直接使用 limit 分頁查詢會越來越慢。
select id,name from product limit 89757, 20
優(yōu)化如下:可以取前一頁的最大行數的 id,然后根據這個最大的 id 來限制下一頁的起點。此列中,上一頁最大的 id 是 89756。SQL 可以采用如下的寫法:
//方案一 :返回上次查詢的最大記錄(偏移量)
select id,name from product where id> 89756 limit 20
//方案二:order by + 索引
select id,name from product order by id limit 10000,10
//方案三:在業(yè)務允許的情況下限制頁數
理由如下:
當偏移量最大的時候,查詢效率就會越低,因為 MySQL 并非是跳過偏移量直接去取后面的數據,而是先把偏移量+要取的條數,然后再把前面偏移量這一段的數據拋棄掉再返回的。
如果使用優(yōu)化方案一,返回上次最大查詢記錄(偏移量),這樣可以跳過偏移量,效率提升不少。
方案二使用 order by+索引,也是可以提高查詢效率的。
方案三的話,建議跟業(yè)務討論,有沒有必要查這么多的分頁。因為絕大多數用戶都不會往后翻太多頁。
【強制】 在代碼中寫分頁查詢邏輯時,若 count 為 0 應直接返回,避免執(zhí)行后面的分頁語句。
總結
以上是生活随笔為你收集整理的mysql分页limit运算,MySQL的limit分页查询及性能问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php九宫格代码,用php数字九宫格.
- 下一篇: 多参量最优化matlab,fmincon