mysql中的回表查詢與索引覆蓋

瞭解一下MySQL中的回表查詢與索引覆蓋。數據庫

回表查詢緩存

要說回表查詢,先要從InnoDB的索引實現提及。InnoDB有兩大類索引,一類是彙集索引(Clustered Index),一類是普通索引(Secondary Index)。性能

InnoDB的彙集索引優化

InnoDB彙集索引的葉子節點存儲行記錄,所以InnoDB必需要有且只有一個彙集索引。spa

1.若是表定義了PK(Primary Key,主鍵),那麼PK就是彙集索引。操作系統

2.若是表沒有定義PK,則第一個NOT NULL UNIQUE的列就是彙集索引。指針

3.不然InnoDB會另外建立一個隱藏的ROWID做爲彙集索引。code

這種機制使得基於PK的查詢速度很是快,由於直接定位的行記錄。blog

InnoDB的普通索引索引

InnoDB普通索引的葉子節點存儲主鍵值(MyISAM則是存儲的行記錄頭指針)。

什麼是回表查詢

假設有個t表(id PK, name KEY, sex, flag),這裏的id是彙集索引,name則是普通索引。

表中有四條記錄:

id name sex flag
1 sj m A
3 zs m A
5 ls m A
9 ww f B

彙集索引的B+樹索引(id是PK,葉子節點存儲行記錄):

普通索引的B+樹索引(name是KEY,葉子節點存儲PK值,即id):

普通索引由於沒法直接定位行記錄,其查詢過程在一般狀況下是須要掃描兩遍索引樹的。

select * from t where name = 'lisi';

這裏的執行過程是這樣的:

粉紅色的路徑須要掃描兩遍索引樹,第一遍先經過普通索引定位到主鍵值id=5,而後第二遍再經過彙集索引定位到具體行記錄。這就是所謂的回表查詢,即先定位主鍵值,再根據主鍵值定位行記錄,性能相對於只掃描一遍彙集索引樹的性能要低一些。

索引覆蓋

索引覆蓋是一種避免回表查詢的優化策略。具體的作法就是將要查詢的數據做爲索引列創建普通索引(能夠是單列索引,也能夠一個索引語句定義全部要查詢的列,即聯合索引),這樣的話就能夠直接返回索引中的的數據,不須要再經過彙集索引去定位行記錄,避免了回表的狀況發生。

覆蓋索引的定義與注意事項

若是一個索引覆蓋(包含)了全部須要查詢的字段的值,這個索引就是覆蓋索引。由於索引中已經包含了要查詢的字段的值,所以查詢的時候直接返回索引中的字段值就能夠了,不須要再到表中查詢,避免了對主鍵索引的二次查詢,也就提升了查詢的效率。

要注意的是,不是全部類型的索引均可以成爲覆蓋索引的。由於覆蓋索引必需要存儲索引的列值,而哈希索引、空間索引和全文索引等都不存儲索引列值,索引MySQL只能使用B-Tree索引作覆蓋索引。

另外,當發起一個被索引覆蓋的查詢(索引覆蓋查詢)時,在explain(執行計劃)的Extra列能夠看到【Using Index】的信息。

覆蓋索引的優勢

1.索引條目一般遠小於數據行的大小,由於覆蓋索引只須要讀取索引,極大地減小了數據的訪問量。

2.索引是按照列值順序存儲的,對於IO密集的範圍查找會比隨機從磁盤讀取每一行數據的IO小不少。

3.一些存儲引擎好比MyISAM在內存中只緩存索引,數據則依賴操做系統來緩存,所以要訪問數據的話須要一次系統調用,使用覆蓋索引則避免了這一點。

4.因爲InnoDB的聚簇索引,覆蓋索引對InnoDB引擎下的數據庫表特別有用。由於InnoDB的二級索引在葉子節點中保存了行的主鍵值,若是二級索引可以覆蓋查詢,就避免了對主鍵索引的二次查詢。

 

"時刻保持謙虛,高情商是軟實力。"

相關文章
相關標籤/搜索