參考:https://www.cnblogs.com/myseries/p/11265849.html
InnoDB有兩大類索引:聚集索引(clustered index)和普通索引(secondary index)
nnoDB聚集索引的葉子節點存儲行記錄,因此, InnoDB必須要有,且只有一個聚集索引:
(1)如果表定義了PK,則PK就是聚集索引;
(2)如果表沒有定義PK,則第一個not NULL unique列是聚集索引;
(3)否則,InnoDB會創建一個隱藏的row-id作為聚集索引;
InnoDB普通索引的葉子節點存儲主鍵值。
兩個B+樹索引分別如上圖:
(1)id為PK,聚集索引,葉子節點存儲行記錄;
(2)name為KEY,普通索引,葉子節點存儲PK值,即id;
既然從普通索引無法直接定位行記錄,那普通索引的查詢過程是怎么樣的呢?
通常情況下,需要掃碼兩遍索引樹。
這就是所謂的回表查詢,先定位主鍵值,再定位行記錄,它的性能較掃一遍索引樹更低。
總結:回表查詢就是查詢時先定位主鍵值,再定位行記錄,會查詢2次索引樹。
|
如何實現索引覆蓋?
常見的方法是:將被查詢的字段,建立到聯合索引里去。
如將下面第二個查詢中sex加入到聯合索引中,就不需要回表了。
select id,name from user where name='shenjian';
能夠命中name索引,索引葉子節點存儲了主鍵id,通過name的索引樹即可獲取id和name,無需回表,符合索引覆蓋,效率較高。
explain sql 顯示 Extra:Using index。說明沒有回表
select id,name,sex from user where name='shenjian';
能夠命中name索引,索引葉子節點存儲了主鍵id,但sex字段必須回表查詢才能獲取到,不符合索引覆蓋,需要再次通過id值掃碼聚集索引獲取sex字段,效率會降低。
explain sql 顯示 Extra:Using index condition。說明需要回表
詳細描述見本文第一行引用的鏈接
select
id,
name
from
user
where
name
=
'shenjian'
;
|