成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這真的不是八股!經典 MySQL 大數據量查詢分頁問題

數據庫 MySQL
從業務角度來說,可以認為超過這個最大值用戶已經不是在分頁了,而是在刷數據,如果確實是要找某條數據,那么正常理解應該是輸入合適的條件來適當縮小范圍,而不是一頁一頁地分頁。

查詢分頁一般要最少要執行兩條 SQL 語句:

SELECT COUNT(*) FROM tablename WHERE columnName = 'xx'
SELECT * FROM tablename WHERE columnName = 'xx' limit 0,100

正常情況下沒有問題,但是當數據量非常大的時候,首先 count(*) 會非常慢這是肯定的,其次分頁越多,limit 的效率就會越低。

比如 limit 200000, 10,這個等同于數據庫要掃描出 200010 條數據,然后再丟棄前面的 200000 條數據,返回剩下 10 條數據給用戶,這種取法很明顯越往后速度越慢,妥妥的慢 SQL。

《高性能 MySQL》中對這個問題有過說明:

分頁操作通常會使用 limit 加上偏移量的辦法實現,同時再加上合適的 order by 子句。但這會出現一個常見問題:當偏移量非常大的時候,它會導致 MySQL 掃描大量不需要的行然后再拋棄掉。

數據模擬

我們創建兩張表(部門表和員工表),并模擬插入 500w 條員工數據

圖片

測試下分頁查詢員工的 SQL 執行速度,先來看偏移量比較小的情況:

SELECT a.empno,a.empname,a.job,b.depno,b.depname
from emp a 
left join dep b 
on a.depno = b.depno 
order by a.id 
desc limit 100,25;

受影響的行: 0
時間: 0.001s

再來看下偏移量非常大的情況:

SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a 
left join dep b 
on a.depno = b.depno 
order by a.id 
desc limit 4800000,25;

受影響的行: 0
時間: 12.275s

可以很明顯的看出,偏移量很小的時候,查詢速度還是非??斓?,當偏移量上到百萬量級,這個執行時間已經無法忍受了,一條查詢語句跑十幾秒這不直接給數據庫干阻塞了?

優化方案

使用覆蓋索引 + 子查詢

偏移量之前的數據是沒有價值的,所以我們可以先在聚集索引中根據偏移量找到開始位置的 id 值,再根據這個 id 值去非聚集索引上查詢所需要的行數據,這樣就避免了大量的無用的回表查詢。

總結來說就是:利用子查詢獲取偏移 n 條的位置 id,基于這個位置再往后取

SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a 
left join dep b 
on a.depno = b.depno
where 
 a.id >= (select id from emp order by id limit 4800000,1)
order by a.id 
limit 25;

受影響的行: 0
時間: 1.541s

可以看見,執行效率有顯著提升

記錄上次查找位置

這個應該是比較常見的解決手段了,就是記住上次查找結果的主鍵位置,從而避免使用偏移量。

比如存儲了上次分頁的最后一條數據 id 是 4800000,SQL 就可以直接跳過4800000,從 4800001 開始掃描表

SELECT a.id,a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a 
left join dep b 
on a.depno = b.depno
where 
 a.id > 4800000
order by a.id 
limit 25;

受影響的行: 0
時間: 0.000s

這個效率是最好的,無論怎么分頁,耗時基本都是一致的,因為他執行完條件之后,都只掃描了 25 條數據。

但這種方案只適合順序分頁(比如 Feeds 流場景),這樣才能記住前一個分頁的最后 id。如果用戶跳著分頁,比如剛剛刷完第 25 頁,馬上跳到 35 頁,使用這種方案的話,數據顯示的其實是 26 頁的數據,而不是 35 頁的。

降級

這種方案屬于兜底策略:為 limit 和 offset 設置一個最大值,超過這個最大值,分頁查詢接口就直接返回空數據或者返回錯誤碼。

從業務角度來說,可以認為超過這個最大值用戶已經不是在分頁了,而是在刷數據,如果確實是要找某條數據,那么正常理解應該是輸入合適的條件來適當縮小范圍,而不是一頁一頁地分頁。

責任編輯:武曉燕 來源: 飛天小牛肉
相關推薦

2018-09-06 16:46:33

數據庫MySQL分頁查詢

2021-10-26 14:40:03

MySQL SQL 語句數據庫

2023-11-29 17:28:07

2021-11-04 14:32:17

Spring 面試作用域

2021-10-21 14:43:23

Java 語言 Java 基礎

2021-07-26 14:59:23

面試Redis內存數據庫

2021-09-07 14:46:42

面試網絡HTTP 協議

2018-05-15 08:44:44

TensorFlowKeras內存

2022-05-06 22:13:56

JVM垃圾收集算法

2023-11-28 18:09:49

Java多態

2021-10-26 17:05:55

Redis字符串復雜度

2022-09-03 11:36:11

Python文件網絡

2011-04-18 11:13:41

bcp數據導入導出

2011-08-16 09:21:30

MySQL大數據量快速語句優化

2021-01-07 07:46:34

MyBatis 數據量JDBC

2021-08-01 22:59:43

Object八股文quals

2015-03-09 10:40:44

MySQL大量數據插入

2009-12-08 15:19:58

WCF大數據量

2018-07-11 20:07:06

數據庫MySQL索引優化

2010-07-29 13:30:54

Hibari
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产99热精品 | 另类视频在线 | 国产午夜视频 | 暖暖成人免费视频 | 亚洲国产精品成人无久久精品 | 一区二区三区视频在线 | 国产精品日韩欧美一区二区三区 | 亚洲精品久久久久中文字幕欢迎你 | 欧美不卡一区二区 | 日韩精品一区二区三区中文在线 | 天天噜天天干 | 一区二区三区免费 | 激情五月婷婷综合 | 欧美日韩不卡合集视频 | 国产免费一区二区三区最新6 | 国产一级一级毛片 | 久久久久久毛片免费观看 | 亚洲v日韩v综合v精品v | 欧美a级成人淫片免费看 | 精精国产xxxx视频在线播放7 | 成在线人视频免费视频 | 亚洲伊人a | 亚洲欧洲中文 | 成人精品一区二区三区中文字幕 | 蜜桃视频一区二区三区 | 有码一区 | 男人天堂久久久 | 久久精品亚洲精品国产欧美 | 老牛影视av一区二区在线观看 | 亚洲精品乱码久久久久久按摩观 | 日韩区| a在线观看免费 | 龙珠z在线观看 | 国产高潮av | 黄a大片| 日韩欧美一区二区三区四区 | 国产成人啪免费观看软件 | 午夜视频在线免费观看 | 一区二区三区在线免费 | 精品国产一区二区久久 | 亚洲国产成人精品女人久久久野战 |