1. 程式人生 > 其它 >mysql學習筆記(五)索引(下)

mysql學習筆記(五)索引(下)

表初始語句

mysql> create table T (
ID int primary key,
k int NOT NULL DEFAULT 0, 
s varchar(16) NOT NULL DEFAULT '',
index k(k))
engine=InnoDB;

insert into T values(100,1, 'aa'),(200,2,'bb'),(300,3,'cc'),(500,5,'ee'),(600,6,'ff'),(700,7,'gg');

在表 T 中,執行 select * from T where k between 3 and 5 的執行過程如下:

在 k 索引樹上找到 k=3 的記錄,取得 ID = 300;

再到 ID 索引樹查到 ID=300 對應的 R3;

在 k 索引樹取下一個值 k=5,取得 ID=500;

再回到 ID 索引樹查到 ID=500 對應的 R4;

在 k 索引樹取下一個值 k=6,不滿足條件,迴圈結束。

在這個過程中,回到主鍵索引樹搜尋的過程,我們稱為回表。可以看到,這個查詢過程讀了 k 索引樹的 3 條記錄(步驟 1、3 和 5),回表了兩次(步驟 2 和 4)。

覆蓋索引

如果執行的語句是 select ID from T where k between 3 and 5,這時只需要查 ID 的值,而 ID 的值已經在 k 索引樹上了,因此可以直接提供查詢結果,不需要回表。也就是說,在這個查詢裡面,索引 k 已經“覆蓋了”我們的查詢需求,我們稱為覆蓋索引。

當然,索引欄位的維護總是有代價的。因此,在建立冗餘索引來支援覆蓋索引時就需要權衡考慮了。

最左字首原則

B+ 樹這種索引結構,可以利用索引的“最左字首”,來定位記錄。

只要滿足最左字首,就可以利用索引來加速檢索。這個最左字首可以是聯合索引的最左 N 個欄位,也可以是字串索引的最左 M 個字元

如果安排聯合索引的位置?

第一原則,通過調整順序,可以少維護一個索引,那麼這個順序就是優先考慮的

考慮空間,例如 name 欄位是比 age 欄位大的 ,那我就建議你建立一個(name,age) 的聯合索引和一個 (age) 的單欄位索引。

索引下堆

在 MySQL 5.6 之前,只能從 ID3 開始一個個回表。到主鍵索引上找出資料行,再對比欄位值。

而 MySQL 5.6 引入的索引下推優化(index condition pushdown), 可以在索引遍歷過程中,對索引中包含的欄位先做判斷,直接過濾掉不滿足條件的記錄,減少回表次數。

 

參考地址:
https://time.geekbang.org/column/article/69636