日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql分页limit运算,MySQL的limit分页查询及性能问题

發(fā)布時(shí)間:2025/3/15 数据库 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql分页limit运算,MySQL的limit分页查询及性能问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

MySQL 通過 limit 實(shí)現(xiàn)分頁(yè)查詢。limit 接收一個(gè)或兩個(gè)整數(shù)型參數(shù)。如果是兩個(gè)參數(shù),第一個(gè)指定返回記錄行的偏移量,第二個(gè)指定返回記錄行的最大數(shù)目。初始記錄行的偏移量是 0。為了與 PostgreSQL 兼容,limit 也支持limit a offset b【a:取的記錄數(shù);b:索引】。

一、分頁(yè)查詢

客戶端通過傳遞 start(頁(yè)碼),pageSize(每頁(yè)顯示的條數(shù))兩個(gè)參數(shù)去分頁(yè)查詢數(shù)據(jù)庫(kù)表中的數(shù)據(jù)。MySql 數(shù)據(jù)庫(kù)提供的分頁(yè)函數(shù) limit m,n 用法和實(shí)際需求不切合,所以就需要根據(jù)實(shí)際情況去改寫適合分頁(yè)的語(yǔ)句。

1??查詢第1條到第10條的數(shù)據(jù)select * from table limit 0,10;

--->對(duì)應(yīng)需求就是查詢第一頁(yè)的數(shù)據(jù):select * from table limit (1-1)*10,10;

2??查詢第11條到第20條的數(shù)據(jù)select * from table limit 10,10;

--->對(duì)應(yīng)需求就是查詢第二頁(yè)的數(shù)據(jù):select * from table limit (2-1)*10,10;

3??查詢第21條到第30條的數(shù)據(jù)select * from table limit 20,10;

--->對(duì)應(yīng)需求就是查詢第三頁(yè)的數(shù)據(jù):select * from table limit (3-1)*10,10;

由此,得出符合需求的分頁(yè) sql 格式是:select * from table limit (start-1)*pageSize,pageSize;其中 start 是頁(yè)碼,pageSize 是每頁(yè)顯示的條數(shù)。

二、性能問題

對(duì)于小的偏移量,直接用 limit 查詢沒有什么問題。隨著數(shù)據(jù)量的增大,越往后分頁(yè),limit 語(yǔ)句的偏移量越大,速度也會(huì)明顯變慢。

優(yōu)化思想:

避免數(shù)據(jù)量大時(shí)掃描過多的記錄

解決:

子查詢的分頁(yè)方式或者 JOIN 分頁(yè)方式。JOIN 分頁(yè)和子查詢分頁(yè)的效率基本在一個(gè)等級(jí)上,消耗的時(shí)間也基本一致。

一般 MySQL 的主鍵是自增的數(shù)字類型,這種情況下可以使用下面的方式進(jìn)行優(yōu)化。以真實(shí)的生產(chǎn)環(huán)境的6萬(wàn)條數(shù)據(jù)的一張表為例,比較一下優(yōu)化前后的查詢耗時(shí):

-- 傳統(tǒng) limit,文件掃描

select * from table order by id limit 50000,2;

受影響的行: 0

時(shí)間: 0.171s

-- 子查詢方式,索引掃描

select * from table

where id >= (select id from table order by id limit 50000 , 1)

limit 2;

受影響的行: 0

時(shí)間: 0.035s

-- JOIN 分頁(yè)方式

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

時(shí)間: 0.036s

可以看到經(jīng)過優(yōu)化性能提高了很多倍。

優(yōu)化原理:

子查詢是在索引上完成的,而普通的查詢是在數(shù)據(jù)文件上完成的。通常來(lái)說,索引文件要比數(shù)據(jù)文件小得多,所以操作起來(lái)也會(huì)更有效率。因?yàn)橐〕鏊凶侄蝺?nèi)容,普通查詢需要跨越大量數(shù)據(jù)塊并取出,而另一種方式直接根據(jù)索引字段定位后,才取出相應(yīng)內(nèi)容,效率自然大大提升。因此,對(duì) limit 的優(yōu)化,是避免直接使用 limit,而是首先獲取到 offset 的 id,然后直接使用 limit size 來(lái)獲取數(shù)據(jù)。

在實(shí)際項(xiàng)目使用,可以利用類似策略模式的方式去處理分頁(yè)。例如,每頁(yè) 100 條數(shù)據(jù),判斷如果是 100 頁(yè)以內(nèi),就使用最基本的分頁(yè)方式;如果大于 100,則使用子查詢的分頁(yè)方式。

三、limit 優(yōu)化。使用合理的分頁(yè)方式以提高分頁(yè)的效率

使用 limit 實(shí)現(xiàn)分頁(yè)邏輯。不僅提高了性能,同時(shí)減少了不必要的數(shù)據(jù)庫(kù)和應(yīng)用間的網(wǎng)絡(luò)傳輸。

查詢結(jié)果只有一條或者只要最大/最小一條記錄,建議用 limit 1。這是為了使 explain 中 type 列達(dá)到 const 類型。“l(fā)imit 1”可以避免全表掃面,只要找到了對(duì)應(yīng)的一條記錄,就不會(huì)繼續(xù)向下掃描了,效率將會(huì)大大提高。當(dāng)然,如果查詢字段是唯一索引的話,沒必要加 limit 1,因?yàn)?limit 的存在主要就是為了防止全表掃描,從而提高性能,如果一個(gè)語(yǔ)句本身可以預(yù)知不用全表掃描,有沒有 limit ,性能的差別并不大。

使用下面 SQL 語(yǔ)句做分頁(yè)的時(shí)候,隨著表數(shù)據(jù)量的增加,直接使用 limit 分頁(yè)查詢會(huì)越來(lái)越慢。

select id,name from product limit 89757, 20

優(yōu)化如下:可以取前一頁(yè)的最大行數(shù)的 id,然后根據(jù)這個(gè)最大的 id 來(lái)限制下一頁(yè)的起點(diǎn)。此列中,上一頁(yè)最大的 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è)務(wù)允許的情況下限制頁(yè)數(shù)

理由如下:

當(dāng)偏移量最大的時(shí)候,查詢效率就會(huì)越低,因?yàn)?MySQL 并非是跳過偏移量直接去取后面的數(shù)據(jù),而是先把偏移量+要取的條數(shù),然后再把前面偏移量這一段的數(shù)據(jù)拋棄掉再返回的。

如果使用優(yōu)化方案一,返回上次最大查詢記錄(偏移量),這樣可以跳過偏移量,效率提升不少。

方案二使用 order by+索引,也是可以提高查詢效率的。

方案三的話,建議跟業(yè)務(wù)討論,有沒有必要查這么多的分頁(yè)。因?yàn)榻^大多數(shù)用戶都不會(huì)往后翻太多頁(yè)。

【強(qiáng)制】 在代碼中寫分頁(yè)查詢邏輯時(shí),若 count 為 0 應(yīng)直接返回,避免執(zhí)行后面的分頁(yè)語(yǔ)句。

總結(jié)

以上是生活随笔為你收集整理的mysql分页limit运算,MySQL的limit分页查询及性能问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。