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

MySQL遵循最左前綴匹配原則!面試官:回去等通知吧

數據庫 MySQL
MySQL 8.0.13 版本中,對于range查詢(什么是range后面會提到),引入了索引跳躍掃描(Index Skip Scan)優化,支持不符合組合索引最左前綴原則條件下的SQL,依然能夠使用組合索引,減少不必要的掃描。

我們都知道,MySQL的Innodb引擎中,索引是通過B+樹來實現的。不管是普通索引還是聯合索引,都需要構造一個B+樹的索引結構。

那么,我們都知道普通索引的存儲結構中在B+樹的每個非節點上記錄的索引的值,而這棵B+樹的葉子節點上記錄的是聚簇索引(主鍵索引)的值。

如:

圖片

那么,如果是聯合索引的話,這棵B+樹又是如何存儲的呢?

在聯合索引中,聯合索引(name,age)也是一個B+樹,非葉子節點中記錄的是name,age兩個字段的值,葉子節點中記錄的是name,age兩個字段以及主鍵id的值。

圖片

?在存儲的過程中,如上圖所示,當age不同時,按照age排序,當age相同時,則按照name排序。

所以,了解了索引的存儲結構之后,我們就很容易理解最左前綴匹配了:因為索引底層是一個B+樹,如果是聯合索引的話,在構造B+樹的時候,會先按照左邊的key進行排序,左邊的key相同時再依次按照右邊的key排序。

所以,在通過索引查詢的時候,也需要遵守最左前綴匹配的原則,也就是需要從聯合索引的最左邊開始進行匹配,這時候就要求查詢語句的where條件中,包含最左邊的索引的值。

在了解了最左前綴匹配之后,日常我們在工作中,經常在簡歷索引以及查詢的時候,都會基于這個默認的約定進行索引的設計和SQL的優化。

大家都默認MySQL一定是遵循最左前綴匹配的。會認為當一個age,name的聯合索引存在時,如果查詢語句中不包含age作為條件,就一定不走索引。

MySQL一定是遵循最左前綴匹配的,這句話在以前是正確的,沒有任何毛病。但是在MySQL 8.0中,就不一定了。?

索引跳躍掃描

MySQL 8.0.13 版本中,對于range查詢(什么是range后面會提到),引入了索引跳躍掃描(Index Skip Scan)優化,支持不符合組合索引最左前綴原則條件下的SQL,依然能夠使用組合索引,減少不必要的掃描。

通過一個例子給大家解釋一下,首先有下面這樣一張表(參考了MySQL官網的例子,但是我做了些改動和優化):

圖片

通過上面的SQL,先創建一張t1表,并把f1,f2兩個字段設置為聯合索引。之后再向其中插入一些記錄。

分別在MySQL 5.7.9和MySQL 8.0.30上執行:

圖片

執行結果如下:

圖片

可以看到,主要有以下幾個區別:

MySQL 5.7中,type = index,rows=160,extra=Using where;Using index

MySQL 8.0中,type = range,rows=16,extra=Using where;Using index for skip scan

這里面的type指的是掃描方式,range表示的是范圍掃描,index表示的是索引樹掃描,通常情況下,range要比index快得多。

從rows上也能看得出來,使用index的掃描方式共掃描了160行,而使用range的掃描方式只掃描了16行。

?接著,重點來了,那就是為啥MySQL 8.0中的掃描方式可以更快呢?主要是因為Using index for skip scan 表示他用到了索引跳躍掃描的技術。

也就是說,雖然我們的SQL中,沒有遵循最左前綴原則,只使用了f2作為查詢條件,但是經過MySQL 8.0的優化以后,還是通過索引跳躍掃描的方式用到了索引了。?

優化原理

在MySQL 8.0.13 及以后的版本中,SELECT f1, f2 FROM t1 WHERE f2 = 40;SQL執行過程如下:

  • 獲取f1字段第一個唯一值,也就是f1=1。
  • 構造f1=1 and f2 = 40,進行范圍查詢。
  • 獲取f1字段第二個唯一值,也就是f1=2。
  • 構造f1=2 and f2 = 40,進行范圍查詢。
  • 一直掃描完f1字段所有的唯一值,最后將結果合并返回。

也就是說,最終執行的SQL語句是像下面這樣的:?

圖片

即,MySQL的優化器幫我們把聯合索引中的f1字段作為查詢條件進行查詢了。

限制條件

?在知道了索引跳躍掃描的執行過程之后,很多聰明的讀者其實就會發現,這種查詢優化比較適合于f1的取值范圍比較少,區分度不高的情況,一旦f1的區分度特別高的話,這種查詢可能會更慢。

所以,真正要不要走索引跳躍掃描,還是要經過MySQL的優化器進行成本預估之后做決定的。

所以,這種優化一般用于那種聯合索引中第一個字段區分度不高的情況。但是話又說回來了,我們一般不太會把區分度不高的字段放在聯合索引的左邊,不過事無絕對,既然MySQL給了一個優化的方案,就說明還是有這樣的訴求的。

但是,我們不能依賴他這個優化,建立索引的時候,還是優先把區分度高的,查詢頻繁的字段放到聯合索引的左邊。?

除此之外,在MySQL官網中,還提到索引跳躍掃描還有一些其他的限制條件:

  • 表T至少有一個聯合索引,但是對于聯合索引(A,B,C,D)來說,A和D可以是空的,但B和C必須是非空的。
  • 查詢必須只能依賴一張表,不能多表JOIN。
  • 查詢中不能使用GROUP BY或DISTINCT語句?。
  • 查詢的字段必須是索引中的列。
責任編輯:姜華 來源: Hollis
相關推薦

2025-02-13 00:00:00

TCP網絡通信

2020-12-16 08:05:54

Mybatis面試動態代理

2024-05-27 09:23:23

2020-12-02 06:12:27

TCPIP面試

2021-02-06 09:21:17

MySQL索引面試

2022-11-16 17:10:25

MySQL數據事務

2024-02-26 12:38:21

MySQLInnoDB跨度

2021-12-09 07:22:52

索引下推前綴

2022-09-29 07:30:57

數據庫索引字段

2024-08-05 01:26:54

2023-09-01 15:27:31

2022-03-21 09:05:18

volatileCPUJava

2023-07-13 08:19:30

HaspMapRedis元素

2020-12-14 08:07:06

Mybatis源碼java

2024-01-15 06:42:00

高并發熱點賬戶數據庫

2022-05-23 08:43:02

BigIntJavaScript內置對象

2025-03-26 01:25:00

MySQL優化事務

2024-06-12 09:23:37

2024-08-21 10:28:54

Redis數據結構內存

2022-11-15 17:45:46

數據庫MySQL
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区久久 | 日韩资源| 亚洲免费在线观看 | 激情一区二区三区 | 成人性视频免费网站 | 9久久婷婷国产综合精品性色 | 午夜国产一级 | 国产极品车模吞精高潮呻吟 | 91久久久久久 | 欧美精品一区二区三区蜜桃视频 | 黄色电影在线免费观看 | 国产一区二区三区免费视频 | 亚洲精品免费在线观看 | 欧美中文字幕 | 欧美日韩一区在线观看 | 欧美日韩国产一区二区三区 | 久久久久综合 | 欧美一级欧美一级在线播放 | 亚洲成人网在线观看 | 夜久久 | 先锋资源在线 | 欧美国产日韩精品 | 国产精品伦一区二区三级视频 | 日本a视频 | 在线观看中文字幕 | 久久精品视频亚洲 | 精品国产精品国产偷麻豆 | 天天综合网7799精品 | 欧美日韩综合一区 | 国产91亚洲精品一区二区三区 | 亚洲成网站 | 中文字幕免费 | 欧美成人激情 | 国产精品久久久久久久久久久久午夜片 | 国产伦精品一区二区三区照片91 | 黄色小视频大全 | 精品一区二区电影 | 亚洲国产成人精品女人 | 国产精品亚洲欧美日韩一区在线 | 欧美小视频在线观看 | 欧美国产精品一区二区三区 |