MySQL學習筆記(四)索引(下)

2021-09-22 22:48:05 字數 2859 閱讀 8922

在上述那個表中,如果執行了select * from t where k between 3 and 5,需要執行幾次樹的搜尋操作,會掃瞄多少行?

表的初始化語句:

現在看看select * from t where k between 3 and 5這條sql查詢語句的執行流程:

1、在k索引樹上找到k=3記錄,取得id=300

2、再到id索引樹上查到id=300對應r3

3、在k索引樹取下乙個值k=5,取得id=500

4、再回到id索引樹查到id=500對應的r4

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

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

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

由於覆蓋索引可以減少樹的搜尋次數,顯著提公升查詢效能,所以使用覆蓋索引是乙個常用的效能優化手段。

在乙個市民資訊表上,是否有必要將身份證號和名字建立聯合索引?

假設市民表的定義是這樣的:

create table `tuser` (

`id` int(11) not null,

`id_card` varchar(32) default null,

`name` varchar(32) default null,

`age` int(11) default null,

`ismale` tinyint(1) default null,

primary key (`id`),

key `id_card` (`id_card`),

key `name_age` (`name`,`age`)

) engine=innodb

如果根據身份證號查詢市民資訊的需求,只需要在身份證號上面建立索引就夠了。而再建立乙個(身份證號、名字)的聯合索引,是不是浪費空間?

如果有乙個高頻請求,要根據市民的身份證號來查詢姓名,這個聯合索引就有意義,它可以在這個高頻請求上用到覆蓋索引,不再需要回表查整行記錄,減少語句的執行時間。

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

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

用(name, age)這個聯合索引來分析。

索引項是按照索引定義裡面出現的字段順序排序的。

當查詢所有名字是「張三」的人時,可以快速定義到id4,然後向後遍歷得到所有需要的結果。

如果要查的所有名字第乙個字是「張」。那條件為「 where name like '張 %' 」。這時查詢到第乙個符合條件的記錄是id3,然後向後遍歷,直到不滿足條件為止。

這個最左字首可以是聯合索引的最左n個字段,也可以是字串索引的最左m個字元。

所以在建立聯合索引時,如何安排索引內的字段順序?

第一原則是,如果通過調整順序,可以少維護乙個索引,那麼這個順序往往就是需要優先考慮採用的。

查詢條件裡面只有b的語句,是無法使用(a,b)這個聯合索引的,這時不得不維護另外乙個索引,也就是說需要同時維護(a,b)(b)這兩個索引。

這時候需要考慮的就是空間。比如name欄位是比age欄位大的,那就建議建立乙個(name,age)的聯合索引和乙個(age)單字段索引。

以上面的聯合索引(name, age)為例。如果現在有乙個需求:檢索出表中"名字第乙個字是張,而且年齡是10歲的所有男孩"。那麼,sql語句:

mysql> select * from tuser where name like '張 %' and age=10 and ismale=1;

由字首索引規則,用「張」,找到第乙個滿足條件的記錄id3。然後判斷其他條件是否滿足。

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

無索引下推:

這個圖中特意去掉了age的值,是因為innodb並不會去看age的值,只是按順序把「name第乙個字是『張』 」的記錄一條條取出來回表。因此,需要回表4次。

索引下推:

上兩個圖中,每乙個虛線代表回表一次。

這個圖中對於不等於10的直接跳過,所以只需要回表2次。

mysql索引下推 MySQL中的索引下推

前段時間看了一下資料庫相關知識,出現了索引下推這個名詞,有必要記錄下來作為知識儲備。索引下推用一句話總結是 索引下推是資料庫檢索資料過程中為減少回表次數而做的優化。首先介紹下什麼是資料庫回表,回表是一種資料庫檢索過程。通常發生在使用二級索引檢索非主索引資料的過程中。舉個例子 usertest資料表 ...

MySQL學習筆記(四)索引(上)

經常可能發生,某個sql查詢比較慢,分析完原因後,可能就會想到 給某個欄位加個索引 這樣的方案。索引的出現就是為了提高資料查詢的效率。實現索引的方式有很多種,所以這裡也就引入了索引模型。比較常見的,雜湊表 有序陣列和搜尋樹。雜湊表以鍵值對儲存資料,只要輸入對應的key,就可以找到對應的value。雜...

學習筆記 mysql索引(四) 多列索引

多列索引有兩個意思,乙個是在多個列上建立乙個索引,另乙個意思是在多個列上分別建立索引。比較直觀能夠想到,如果是在多個列上建立乙個索引,那麼如果where條件裡正好又是這些列,那麼將獲得較好的效能。如果分別建立索引,where中又有多個分別建立的索引的列,那mysql優化器將如何處理呢?explain...