聯合索引在B 樹上的結構

2021-09-11 14:44:39 字數 2499 閱讀 6425

前言

最近在學習mysql的儲存引擎和索引的知識。看了許多篇介紹myisam和innodb的索引的例子,都能理解。 

像這張索引圖: 

ps:該圖來自大神張洋的《mysql索引背後的資料結構及演算法原理》一文。

但許多文章講述的都是單列索引,我很好奇聯合索引對應的結構圖是怎樣的。

疑惑:聯合索引的結構是怎樣的

比方說聯合索引 (col1, col2,col3),我知道在邏輯上是先按照col1進行排序再按照col2進行排序最後再按照col3進行排序。因此如果是select * from table where col1 = 1 and col3 = 3的話,只有col1的索引部分能生效。但是其物理結構上這個聯合索引是怎樣存在的,我想不懂。

解答:聯合索引的結構

上網查閱了許多資料,總算有點眉目了。

假設這是乙個多列索引(col1, col2,col3),對於葉子節點,是這樣的: 

ps:該圖改自《mysql索引背後的資料結構及演算法原理》一文的配圖。

也就是說,聯合索引(col1, col2,col3)也是一棵b+tree,其非葉子節點儲存的是第乙個關鍵字的索引,而葉節點儲存的則是三個關鍵字col1、col2、col3三個關鍵字的資料,且按照col1、col2、col3的順序進行排序。

配圖可能不太讓人滿意,因為col1都是不同的,也就是說在col1就已經能確定結果了。自己又畫了乙個圖(有點醜),col1表示的是年齡,col2表示的是姓氏,col3表示的是名字。如下圖: 

ps:對應位址指的是資料記錄的位址。

如圖,聯合索引(年齡, 姓氏,名字),葉節點上data域儲存的是三個關鍵字的資料。且是按照年齡、姓氏、名字的順序排列的。

因此,如果執行的是: 

select * from student where 姓氏='李' and 名字='安'; 

或者 select * from student where 名字='安'; 

那麼當執行查詢的時候,是無法使用這個聯合索引的。因為聯合索引中是先根據年齡進行排序的。如果年齡沒有先確定,直接對姓氏和名字進行查詢的話,就相當於亂序查詢一樣,因此索引無法生效。因此查詢是全表查詢。

如果執行的是: 

select * from student where 年齡=1 and 姓氏='李'; 

那麼當執行查詢的時候,索引是能生效的,從圖中很直觀的看出,age=1的是第乙個葉子節點的前6條記錄,在age=1的前提下,姓氏=』李』的是前3條。因此最終查詢出來的是這三條,從而能獲取到對應記錄的位址。 

如果執行的是: 

select * from student where 年齡=1 and 姓氏='黃' and 名字='安'; 

那麼索引也是生效的。

而如果執行的是: 

select * from student where 年齡=1 and 名字='安'; 

那麼,索引年齡部分能生效,名字部分不能生效。也就是說索引部分生效。

因此我對聯合索引結構的理解就是b+tree是按照第乙個關鍵字進行索引,然後在葉子節點上按照第乙個關鍵字、第二個關鍵字、第三個關鍵字…進行排序。

最左原則

而之所以會有最左原則,是因為聯合索引的b+tree是按照第乙個關鍵字進行索引排列的。

有助於理解聯合索引的乙個例子

from csdn論壇:

假設資料 表t (a,b,c) rowid 為物理位置

rowid a b c

(1)   1 1 1

(2)   2 1 13

(3)   2 2 14

(4)   1 3 3

(5)   2 3 12

(6)   1 2 5

(7)   2 3 9

(8)   1 2 2

(9)   1 3 6

(10)  2 2 11

(11)  2 2 8

(12)  1 1 7

(13)  2 3 15

(14)  1 1 4

(15)  2 1 10

當你建立乙個索引 create index *** on t(a,b), 

則索引檔案邏輯上等同於如下

a b rowid

1 1 1

1 1 12

1 1 14

1 2 6

1 2 8

1 3 4

1 3 9

2 1 2

2 1 15

2 2 3

2 2 10

2 2 11

2 3 5

2 3 7

2 3 13

當select * from t where a=1 and b=3 的時候,

資料庫系統可以直接從索引檔案中直接二分法找到a=1的記錄,

然後再b=3的記錄。

但如果你 where b=3 則需要遍歷這個索引表的全部!

最後這樣的解釋,參考過別人的文章,自己也有思考過,但並不能確定實際上的結構就是這種。但是,也算是學到了許多東西,像是明白了為什麼會有最左原則的存在。 

如果有大神發現有錯,望指教。

聯合索引在B 樹上的結構

一級索引 二級聯合索引 假設這是乙個多列索引 col1,col2,col3 對於葉子節點,是這樣的 ps 該圖改自 mysql索引背後的資料結構及演算法原理 一文的配圖。也就是說,聯合索引 col1,col2,col3 也是一棵b tree,其非葉子節點儲存的是第乙個關鍵字的索引,而葉節點儲存的則是...

聯合索引在B 樹上的結構介紹

最近在學習mysql的儲存引擎和索引的知識。看了許多篇介紹myisam和innodb的索引的例子,都能理解。像這張索引圖 ps 該圖來自大神張洋的 mysql索引背後的資料結構及演算法原理 一文。但許多文章講述的都是單列索引,我很好奇聯合索引對應的結構圖是怎樣的。比方說聯合索引 col1,col2,...

聯合索引 輔助索引 在B 樹的結構

在什麼是索引這篇文章中介紹了索引的常見的資料結構,其對應資料結構的圖是以主鍵索引來講解的。本文我們一起看下聯合使用在b 樹的結構是怎麼樣的?對多個字段同時建立的索引 有順序,abc,cba是完全不同的兩種聯合索引 假設聯合索引為age,name,school組合的 其在b 樹的結構如下 聯合索引的葉...