我們這里創建一個用戶表,表中有字段name,並且在name上有索引
1 create table t_user ( 2 id bigint(20) not null auto_increment , 3 name varchar(255) not null, 4 primary key (id), 5 index index_name (name) using btree) 6 engine=innodb 7 default character set=utf8 collate=utf8_general_ci
兩棵樹的示例示意圖如下
1.主鍵索引:主鍵索引的葉子節點保存着主鍵即對應行的全部數據。在InnoDB里,主鍵索引也被稱為聚簇索引
2.二級索引(非主鍵索引): 二級索引樹中的葉子結點保存着索引值和主鍵值,當使用二級索引進行查詢時,需要進行回表操作。在InnoDB里,非主鍵索引也被稱為二級索引
如何區分主鍵索引和普通索引的查詢
1 select * from t_user where id=1 2 //即主鍵查詢方式,則只需要搜索id這棵B+樹
1 select * from t_user where name="張三" 2 //即普通索引查詢方式,則需要先搜索name索引樹,得到id的值為3,再到id索引樹搜索一次。這個過程稱為回表
所以基於二級索引(非主鍵索引)的查詢需要多掃描一棵索引樹。因此,我們在應用中應該盡量使用主鍵查詢
3.覆蓋索引
1 A: select id from user_table where name= '張三' 2 B: select password from user_table where name= '張三'
語句A: 因為 name索引樹 的葉子結點上保存有 name和id的值 ,所以通過 name索引樹 查找到id后,因此可以直接提供查詢結果,不需要回表,也就是說,在這個查詢里面,索引name 已經 “覆蓋了” 我們的查詢需求,我們稱為 覆蓋索引
語句B: name索引樹 上 找到 name=‘張三’ 對應的主鍵id, 通過回表在主鍵索引樹上找到滿足條件的數據
因此我們可以得知,當sql語句的所求查詢字段(select列)和查詢條件字段(where子句)全都包含在一個索引中(聯合索引),可以直接使用索引查詢而不需要回表。這就是覆蓋索引。