回表
通過上一章的介紹,我們知道索引可以分為主鍵索引和非主鍵索引。非主鍵索引的葉子節點儲存的是主鍵索引的值。
我們在通過非主鍵索引查詢時候,需要先在非主鍵索引樹找到主鍵值,然後再到主鍵索引樹根據主鍵值去查詢出整行資料,這個過程中,回到主鍵索引樹搜尋的過程,我們稱為回表
覆蓋索引
#建立一張表
mysql>
create
table t (
id int
primary
key,
k int
notnull
default0,
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'
);
索引樹的結構為:
對於上面的表我們執行下面這條查詢語句:select id from t where k between 3 and 5
這個時候,輸出列只需要查詢id,而索引樹k上面已經有id資訊了,因此可以直接返回結果,不用再去id主鍵索引樹上搜尋了,就避免了回表。
也就是說,在這個查詢裡面,索引 k 已經「覆蓋了」我們的查詢需求,我們稱為覆蓋索引
。
tips:由於覆蓋索引可以減少樹的搜尋次數,顯著提公升查詢效能,所以使用覆蓋索引是乙個常用的效能優化手段。最左匹配原則例如:我們公司的內部通訊軟體,經常會用員工工號查詢員工姓名,這樣乙個高頻搜尋需求,那麼我們就可以建立乙個(工號,姓名)的聯合索引,通過合理使用聯合索引,來實現覆蓋索引,提高查詢效率。
當然,索引欄位的維護總是有代價的。因此,在建立冗餘索引來支援覆蓋索引時就需要權衡考慮了。
我們建立乙個聯合索引 idx_abc(a,b,c)
查詢條件
索引是否生效
where a=# and b=# and c=#
idx_abc生效
where c=# and b=# and a=#
idx_abc生效(特殊性情況,優化器會處理,最後又會變成abc順序)
where a=# and b=#
idx_abc生效
where a=#
idx_abc生效
where a=# and c=#
idx_abc生效
where b=#
idx_abc不生效
where c=#
idx_abc不生效
where b=# and c=#
idx_abc不生效
可以看到,不只是索引的全部定義,只要滿足最左字首,就可以利用索引來加速檢索。這個最左字首可以是聯合索引的最左 n 個字段,也可以是字串索引的最左 m 個字元。
查詢條件的第乙個一定要和聯合索引順序匹配上,否則索引失效。這個時候,如果我們欄位c才是高頻搜尋條件呢,我們又不能不建索引,所以只能新建乙個idx_c(c)的索引。但是我們是否可以考慮,調整索引順序,將idx_abc(a,b,c)改為idx_abc(c,b,a)呢?這樣我們就不用單獨去建立乙個idx_c索引了。當然這個是否可以這麼修改還是要看實際業務場景。給大家貼個表結構,大家可以親自動手試下如果對於聯合索引idx_ab(a,b),既有聯合的查詢,又有基於a ,b各自的查詢。那我們是建立(a,b)(b)這兩個索引還是建立(b,a)(a)這兩個索引呢?那麼需要考慮單獨的這個索引怎麼樣可以占用更少的磁碟空間
create
table
`t_test`
(`id`
int(11)
default
null
,`a`
varchar
(255
)default
null
,`b`
varchar
(255
)default
null
,`c`
varchar
(255
)default
null
,key
`idx_abc`
(`a`
,`b`
,`c`))
engine
=innodb
default
charset
=utf8;
insert
into
`t_test`
(`id`
,`a`
,`b`
,`c`
)values
('1'
,'a1'
,'b1'
,'c1');
insert
into
`t_test`
(`id`
,`a`
,`b`
,`c`
)values
('2'
,'a2'
,'b2'
,'c3');
#通過explain來看下索引是否生效
explain
select
*from t_test where a=
'a1'
and b=
'b1'
and c=
'c1'
explain
select
*from t_test where a=
'a1'
and b=
'b1'
explain
select
*from t_test where a=
'a1'
explain
select
*from t_test where b=
'b1'
explain
select
*from t_test where c=
'c1'
explain
select
*from t_test where a=
'a1'
and c=
'c1'
explain
select
*from t_test where b=
'b1'
and c=
'c1'
explain
select
*from t_test where c=
'c1'
and b=
'b1'
and a=
'a1'
MySQL innodb索引回表操作,最左匹配
簇集索引 主鍵索引 索引的葉子結點存的所有字段值,非簇集索引 非主鍵索引 索引的葉子結點存的是主鍵欄位的值 回表操作 例子 表table 有主鍵 a,索引b select a,b,c from table where a 1 因為a是簇集索引有所有字段,不會回表查 select a,b,c from...
Mysql索引 回表 索引覆蓋
1.先說什麼是索引?索引是一種資料結構 不同引擎對索引的實現方式不同,innodb採用b 樹作為索引結構。2.聚簇索引 非聚簇索引索引可分為聚簇索引和非聚簇索引兩種。聚簇索引 clustered index 聚簇索引的資料的物理存放順序與索引順序是一致的。非聚簇索引 二級索引 secondary i...
MySQL索引,回表,索引覆蓋
多讀多寫多記錄,多學多練多思考。banana.banuit gang 香柚幫 mysql innodb的主鍵索引是簇集索引,也就是索引的葉子節點存的是整個單條記錄的所有字段值,不是主鍵索引的就是非簇集索引,非簇集索引的葉子節點存的是主鍵欄位的值。回表是什麼意思?就是你執行一條sql語句,需要從兩個b...