主键索引 or 辅助索引?一文告诉你 Mysql limit 优化时的索引选择!
作者 | 吳海存
責編?| 徐威龍
封圖|?CSDN下載于視覺中國
導讀:
本文主要針對limit分頁時,是優先基于主鍵索引還是輔助索引等層面展開分析,對limit及offset的用法以及是否該用索引不會過多贅述。
我們知道,在Mysql中可以通過limit實現快速分頁,但是如果表中數據量較大,則分頁后期可能會十分緩慢,這是由limit的工作機制決定的,比如limit 500000,5的意思掃描滿足條件的500005行,扔掉前面的500000行,返回最后的5行,所以我們在分頁的時候,需要通過相應的索引來快速定位到第500000行,然后將后面的5行數據輸出即可。
那我們在選則索引的時候,是使用主鍵索引還是使用輔助索引呢?若使用輔助索引,那對該輔助索引有沒有什么限制呢?比如該索引所基于的列是不是應該有not null約束呢?因為我們知道,在分頁的時候,要求數據是連續的,而索引里面是不記錄null值的,所以若索引沒有not null約束,則有可能不滿足分頁條件。
對于以上幾個問題,我們通過如下的示例來一一驗證說明,如有疏漏之處,望指正。
實驗環境
MySQL版本:8.0.18
OS版本:CentOS 8.0
【實驗步驟】
1.確認測試表emp中的數據量(若數據量太少,則對比效果不明顯)
2.確認表上索引和not null約束信息
說明: id 上索引為主鍵索引
?????empno上的索引ind2為唯一性非空索引
?????ename 上的索引ind3為非空的普通索引
?????salary ?上的索引為可以為空的普通索引
3.收集最新的統計信息
為了測試的公平性,我們執行一次全表查詢,模擬將表emp的page盡量多地緩存到buffer pool,否則可能會出現后執行的sql直接邏輯讀取了先執行的sql通過物理IO讀到buffer pool的page,會使得對比結果缺乏不可靠性。
為了體現測試效果,我們選擇掃描700W+5行,然后舍棄前面的700W行,返回后面滿足條件的5行。
4.1在分頁的時候通過ID列選擇使用主鍵索引
select * from emp where id >= (select id from emp order by id limit 7000000,1) limit 5;
相應的執行計劃使用了主鍵索引PRIMARY:
可以看到,使用ID主鍵索引的時候,用時為2.87秒。?
4.2使用非空唯一性索引
select * from emp where empno >= (select empno from emp order by empno limit 7000000,1) limit 5;?
相應執行計劃使用了非空唯一性索引ind2:
當使用非主鍵以外的非空唯一性索引時,用時0.85秒。?
4.3使用非空非唯一的索引?
select * from emp where ename >= (select ename from emp order by ename limit 7000000,1) limit 5;
相應執行計劃使用了非空非唯一性索引ind3:當使用非空非唯一性索引時,用時1.95秒。
4.4使用可為null的普通索引
先隨機設置20行salary為null
查5條數據驗證一下:?
更新統計信息:
使用可為null的普通索引進行分頁:
執行計劃使用了可為null非唯一性索引:
當使用可為null非唯一性索引時,用時1.18秒,使用的時間比非唯一性索引ind3時間較短的原因,是因為ind4的key_len是5,而ind3的key_len是82,ind3需要讀取更多的page。
4.5驗證使用可為null的普通索引是否會丟失數據
這里有一個問題,就是ind4里會有null值,使用該列進行分頁的話,是不是由可能會丟失數據呢?使用如下步驟進行驗證:
增到表中salary為null的行數到100
對salary進行排序,然后選擇掃描7999910行,然后舍棄前面的7999890行,返回后面滿足條件的20行,看數據庫返回得行數:
可以發現,當使用可為null的非唯一性索引時,會將null值當作最小值參加排序,不會丟失數據。?
通過實驗驗證,我們可以得出如下結論:
1.當使用非主鍵的唯一性非空索引時,用作分頁效率最高。
2.若使用primary key, 因為innodb時IOT表,所有全索引訪問等同于全表掃描,效率低。
3.若同為普通索引,則和該索引的key長度,選擇率等有關系,若該索引的選擇率較高,則效率會高于primary key,原因同第二條。
4.使用可為null的非唯一性索引時,會將null值當作最小值參加排序,不會丟失數據。
對于本文,你有什么想法?歡迎在評論區和我討論。
作者介紹:
吳海存,10g/11g/12c OCM, Oracle Exadata/Golden Gate 專家, 曾于Amazon和Oracle公司擔任全球業務資深DBA,目前供職于中國農業銀行,擔任資深數據庫專家。
同時,歡迎所有開發者掃描下方二維碼填寫《開發者與AI大調研》,只需2分鐘,便可收獲價值299元的「AI開發者萬人大會」在線直播門票!
推薦閱讀:如何成功構建大規模 Web 搜索引擎架構? “出道” 5 年采用率達 78%,Kubernetes 的成功秘訣是什么? 一群阿里人如何用 10 年自研洛神云網絡平臺?技術架構演進全揭秘!拿下 Gartner 容器產品第一,阿里云打贏云原生關鍵一戰! 大話卷積神經網絡CNN,小白也能看懂的深度學習算法教程,全程干貨建議收藏! 朱廣權李佳琦直播掉線,1.2 億人在線等 “抗疫”新戰術:世衛組織聯合IBM、甲骨文、微軟構建了一個開放數據的區塊鏈項目! 真香,朕在看了!總結
以上是生活随笔為你收集整理的主键索引 or 辅助索引?一文告诉你 Mysql limit 优化时的索引选择!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从代码到 Docker、Kubernet
- 下一篇: 阿里云开放国内首个云端数据库测试平台,云