亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MySQL覆蓋索引和索引跳躍掃描方式

 更新時間:2025年05月17日 09:23:48   作者:拔劍縱狂歌  
這篇文章主要介紹了MySQL覆蓋索引和索引跳躍掃描方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

最近在深入學習MySQL,在學習最左匹配原則的時候,遇到了一個有意思的事情。請聽我細細道來。

我的MySQL版本為8.0.32

可以通過 show variables like 'version'; 查看使用的版本。

準備工作

先建表,SQL語句如下:

create table joint_index_test(
        id int primary key,
        a int,
        b int,
        c int
);
alter table joint_index_test add index index_a_b_c(a,b,c);

表結(jié)構(gòu)非常簡單,4個字段,兩個索引,主鍵索引id和聯(lián)合索引abc。暫時不向表中添加數(shù)據(jù)。

開始測試

接下來我們進行查詢操作和使用explain查看select語句的執(zhí)行

1. 最左匹配原則

explain select * from joint_index_test where a = 3;

這條SQL語句是否走了索引大家基本上都能夠分析出來,基礎比較好的小伙伴甚至可以直接分析出來掃描類型是什么。

執(zhí)行結(jié)果如下圖:

由于where后面的條件是a,遵循聯(lián)合索引的最左匹配原則,會使用索引index_a_b_c,進行查詢。由于我們查詢的列是*,在joint_index_test可以擴展為id,a,b,c,這些列在聯(lián)合索引a,b,c中都可以查詢到。所以MySQL在執(zhí)行的時候,會選擇使用覆蓋索引,不再進行回表查詢?!緀xtra列為Using index】

繼續(xù)進行測試第二條SQL語句

2. 覆蓋索引

explain select * from joint_index_test where b = 3;

根據(jù)最左匹配原則,我們可以判斷出來,第二條SQL語句應該不會使用到index_a_b_c聯(lián)合索引,因為聯(lián)合索引是按照字段的順序從左到右進行構(gòu)建的,也就是從字段a進行從小到大的排序,只有字段a相等的時候才會使用b,c進行排序。也就是說,b、c在全局是無序的,在局部卻是有序的。當我們的條件中缺失聯(lián)合索引最左邊的字段時,MySQL在進行查詢的時候,一般情況下,是不能夠使用到聯(lián)合索引了。

但是也有例外,像上面的這一條SQL語句,執(zhí)行的時候會利用聯(lián)合索引進行全索引掃描,因為我們要查詢的字段在聯(lián)合索引中都可以查詢到,然后將所有查詢到的結(jié)果使用where條件進行篩選。

為什么會優(yōu)先走聯(lián)合索引?

因為二級索引樹的記錄東西很少,就只有「索引列+主鍵值」,而聚簇索引記錄的東西會更多,比如聚簇索引中的葉子節(jié)點則記錄了主鍵值、事務 id、用于事務和 MVCC 的回滾指針以及所有的剩余列。MySQL的查詢是基于成本的,會優(yōu)先原則成本低的查詢方案。

如果我們向joint_index_test表中添加一個name字段,這時候,我們要查詢的所有字段就沒有辦法在聯(lián)合索引中全部找到了,MySQL會放棄聯(lián)合索引,改走全表掃描。

全索引掃描

添加一個name字段后,type從index->ALL

3. 索引跳躍掃描

我們將name字段刪除,表中還只保留 id、a、b、c 四個字段,并向表中生成數(shù)據(jù)。

我們向表中生成一千條數(shù)據(jù),id自增,a對1到6進行枚舉,b、c是int類型的隨機數(shù)。

我們再次執(zhí)行

explain select * from joint_index_test where b = 3;

這條SQL語句,發(fā)現(xiàn)type列和Extra列中的內(nèi)容發(fā)生了變更。

type從index -> range ; Extra列從Using Index -> Using index for skip scan.

之所以發(fā)生了這樣的變化,是MySQL8.0.13后對最左原則失效的情況進行了優(yōu)化。如果我們的聯(lián)合索引構(gòu)建的B+Tree中能夠找到所有查詢的列且where查詢條件沒有遵循最左匹配原則,MySQL會通過索引跳躍掃描進行優(yōu)化處理。提前說明,索引跳躍掃描并不是萬能的,我們在進行SQL查詢的時候還是需要盡可能地遵循最左匹配原則。

接下來,我會根據(jù)MySQL官方文檔對索引跳躍掃描進行解說,感興趣的小伙伴也可以直接點擊文末鏈接,自行閱讀。

在MySQL8.0.13版本之前,執(zhí)行這一條SQL語句,會出現(xiàn) Using where,Using Index 使用索引掃描所有的數(shù)據(jù),之后再利用條件進行過濾,其執(zhí)行type為index對全索引進行掃描,性能僅次于ALL;

從MySQL 8.0.13版本開始,mysql支持多范圍掃描;查詢的條件的每個不同前綴值執(zhí)行子范圍掃描。

例如會對 select * from joint_index_test where b = 3 這條SQL語句通過 distinct a 拆分成六條SQL語句,分別為:

explain select * from joint_index_test where a = 1 and b = 3;
explain select * from joint_index_test where a = 2 and b = 3;
explain select * from joint_index_test where a = 3 and b = 3;
explain select * from joint_index_test where a = 4 and b = 3;
explain select * from joint_index_test where a = 5 and b = 3;
explain select * from joint_index_test where a = 6 and b = 3;

讓拆分后的語句能夠遵循聯(lián)合索引的最左匹配原則進行范圍查詢,之后對所有查詢到的值進行合并,并作為整體返回。

值得一提的是,索引跳躍掃描,并非跳過索引,而是在缺失的前綴索引的不同值之間進行跳躍;使用這種策略減少了訪問的行數(shù),因為MySQL直接跳過不符合的構(gòu)造范圍的行。

還是那一句話,聯(lián)合索引不是萬能的,之中優(yōu)化是基于以下條件的:

  • 只適用于單表查詢;
  • 查詢語句中不能使用GROUP BY或DISTINCT;
  • 只能對聯(lián)合索引中構(gòu)建的B+數(shù)包含的列進行查詢;
  • 缺少的前綴必須是常數(shù),數(shù)字類型的字段
  • 查詢條件必須適用連詞進行連接,比如使用AND或者OR

以上還有一些條件,筆者暫時還沒有看懂,值得一提的是,在滿足上面的所有條件的情況下,索引跳躍掃描并不是一定發(fā)生的,因為對缺失的前綴進行組合是需要成本的。

mysql的查詢永遠會選擇成本最低的方案,而索引跳躍掃描僅僅是其中的一種方案。我們可以將索引跳躍掃描看作是覆蓋索引條件查詢?nèi)笔熬Y的一種優(yōu)化方案。

官方鏈接:MySQL :: MySQL 8.0 Reference Manual :: 10.2.1.2 Range Optimization

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何解決docker無法啟動的問題

    如何解決docker無法啟動的問題

    這篇文章主要介紹了如何解決docker無法啟動的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 詳解MySQL分組排序求Top N

    詳解MySQL分組排序求Top N

    這篇文章主要介紹了詳解MySQL分組排序求Top N的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • MySQL?數(shù)據(jù)類型及最優(yōu)選取規(guī)則

    MySQL?數(shù)據(jù)類型及最優(yōu)選取規(guī)則

    這篇文章主要介紹了MySQL?數(shù)據(jù)類型及最優(yōu)選取規(guī)則,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你的學習有所幫助
    2022-08-08
  • MySQL 5.7.22 二進制包安裝及免安裝版Windows配置方法

    MySQL 5.7.22 二進制包安裝及免安裝版Windows配置方法

    這篇文章通過實例代碼給大家介紹了MySQL 5.7.22 二進制包安裝教程,文章末尾給大家補充介紹了mysql 5.7.22 免安裝版Windows配置方法,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-08-08
  • SQL中EXPLAIN命令的使用方法

    SQL中EXPLAIN命令的使用方法

    這篇文章主要給大家介紹了關(guān)于SQL中EXPLAIN命令的使用方法,文中介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • MySQL處理重復數(shù)據(jù)的學習筆記

    MySQL處理重復數(shù)據(jù)的學習筆記

    在本篇文章里小編給大家分享的是一篇關(guān)于MySQL處理重復數(shù)據(jù)的學習筆記,需要的朋友們可以參考下。
    2020-03-03
  • MySQL如何讓一個表中可以有多個自增列

    MySQL如何讓一個表中可以有多個自增列

    這篇文章主要介紹了MySQL如何讓一個表中可以有多個自增列,自增列可使用?auto_increment?來實現(xiàn),當一個列被標識為?auto_increment?之后,在添加時如果不給此列設置任何值,或給此列設置?NULL?值時,那么它會使用自增的規(guī)則來填充此列
    2022-06-06
  • MySql中使用正則表達式查詢的方法

    MySql中使用正則表達式查詢的方法

    Mysql 使用 REGEXP 關(guān)鍵字指定正則表達式的字符匹配模式。接下來通過本文給大家分享MySql中使用正則表達式查詢的方法,感興趣的朋友一起看看吧
    2017-07-07
  • Mysql 原生語句中save or update 的寫法匯總

    Mysql 原生語句中save or update 的寫法匯總

    這篇文章主要介紹了Mysql 原生語句中save or update 的寫法匯總,非常詳細,需要的朋友可以參考下
    2015-03-03
  • MySQL 8.0.13設置日期為0000-00-00 00:00:00時出現(xiàn)的問題解決

    MySQL 8.0.13設置日期為0000-00-00 00:00:00時出現(xiàn)的問題解決

    這篇文章主要介紹了MySQL 8.0.13設置日期為0000-00-00 00:00:00時出現(xiàn)的問題解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01

最新評論