一級索引算法
二級聯合索引數據結構
假設這是一個多列索引(col1, col2,col3),對於葉子節點,是這樣的:
google
PS:該圖改自《MySQL索引背後的數據結構及算法原理》一文的配圖。code
也就是說,聯合索引(col1, col2,col3)也是一棵B+Tree,其非葉子節點存儲的是第一個關鍵字的索引,而葉節點存儲的則是三個關鍵字col一、col二、col3三個關鍵字的數據,且按照col一、col二、col3的順序進行排序。blog
配圖可能不太讓人滿意,由於col1都是不一樣的,也就是說在col1就已經能肯定結果了。本身又畫了一個圖(有點醜),col1表示的是年齡,col2表示的是姓氏,col3表示的是名字。以下圖:
PS:對應地址指的是數據記錄的地址。排序
如圖,聯合索引(年齡, 姓氏,名字),葉節點上data域存儲的是三個關鍵字的數據。且是按照年齡、姓氏、名字的順序排列的。索引
所以,若是執行的是: select * from STUDENT where 姓氏='李' and 名字='安';
或者 select * from STUDENT where 名字='安';
那麼當執行查詢的時候,是沒法使用這個聯合索引的。由於聯合索引中是先根據年齡進行排序的。若是年齡沒有先肯定,直接對姓氏和名字進行查詢的話,就至關於亂序查詢同樣,所以索引沒法生效。所以查詢是全表查詢。get
若是執行的是: select * from STUDENT where 年齡=1 and 姓氏='李';
那麼當執行查詢的時候,索引是能生效的,從圖中很直觀的看出,age=1的是第一個葉子節點的前6條記錄,在age=1的前提下,姓氏=’李’的是前3條。所以最終查詢出來的是這三條,從而能獲取到對應記錄的地址。
若是執行的是: select * from STUDENT where 年齡=1 and 姓氏='黃' and 名字='安';
那麼索引也是生效的。it
而若是執行的是: select * from STUDENT where 年齡=1 and 名字='安';
那麼,索引年齡部分能生效,名字部分不能生效。也就是說索引部分生效。class
所以我對聯合索引結構的理解就是B+Tree是按照第一個關鍵字進行索引,而後在葉子節點上按照第一個關鍵字、第二個關鍵字、第三個關鍵字…進行排序。
而之因此會有最左原則,是由於聯合索引的B+Tree是按照第一個關鍵字進行索引排列的。