MySQL索引-組合索引


 
示例數據
-- 創建表
create table table1(
col1 int primary key,
col2 int,
col3 int,
col4 int,
col5 varchar(20)
) engine=INNODB;
-- 插入數據
insert into table1 values(4, 3, 1, 1, 'd');
insert into table1 values(1, 1, 1, 1, 'a');
insert into table1 values(8, 8, 8, 8, 'h');
insert into table1 values(2, 2, 2, 2, 'b');
insert into table1 values(5, 2, 3, 5, 'e');
insert into table1 values(3, 3, 2, 2, 'c');
insert into table1 values(7, 4, 5, 5, 'g');
insert into table1 values(6, 6, 4, 4, 'f');
-- 添加組合索引
alter table table1 add index idx_table1_col234(col2, col3, col4);

查詢SQL:select * from table1; 默認按主鍵從小到大排序,如下圖所示

 

組合索引原理
組合索引排序規則:先比較第一個列值的大小進行排序,如果相同,再比較第二列值的大小進行排序,如果再相同,再比較第三列值的大小...依次進行排序。
組合索引(沒有主鍵索引的情況)如下圖所示:
 

 

如圖所示
 
說明:111,表示col2,col3,col4的組合值,藍色表示主鍵
假設:
  • select * from table1 where col2 =2  and col3 =2  and col4 = 5;相當於查詢索引值 = 225;
  • select * from table1 where col2 =2  and col3 =2;相當於查詢索引值 = 22*;
  • select * from table1 where col2 =2;相當於查詢索引值 = 2**;
假設:
  • select * from table1 where col3 =2  and col4 = 5; 即相當於查詢”索引值“ = *25,無法確定其值的大小。索引失效

 

(1)為什么范圍后面的索引全失效?
組合索引中未遵循最左例原則的情況下,索引失效,這個好理解,但是當最左列為范圍查找時,后面那些列的索引不會用到,為什么?
 
 
(2)為什么有時候明明用了索引而不走索引?
select col2, col5 from table1 where col2 > 3;    -- 走索引
select col2 from table1;-- 走索引
select col2 from table1 where col2 > 1;  -- 走索引
select col2, col5 from table1 where col2 > 1;    -- 不走索引
select col1, col2 from table1 where col2 > 1;    -- 走索引

原因:

當執行查詢select col2, col5 from table1 where col2 > 1 時,查詢出來一共會有7條記錄(總記錄8條),因為非聚簇索引,索引與數據是分開的,因此每查詢出來一條數據都要回表查詢一次,這里共要回表7次;即走索引時,需要回表查詢7次,7次IO,而全表掃描時4次,4次IO,mysql優化器自動幫你選擇了走全表掃描。
當執行查詢select col1, col2 from table1 where col2 > 1 時,因為col1屬於主鍵索引,並且數據保存在該組合索引的節點上,因此不需要回表查詢,也就走索引。

 

(3)發生類型轉換時不走索引的原因

select * from table1 where col1 = 'a';    -- 不走索引,字符a會默認轉換為數字0(所有字符都會轉換為0)
select * from table1 where col5 = 1;      -- 不走索引,mysql會將col5列所有字段全部轉換為int類型,因此為不走索引,全表掃描;
同理
select * from table1 where col1 + 1 = 5--也不會走索引,mysql會將 col1列所有字段全部+1操作,所有列全部操作一次,就相當於進行了一次全表掃描

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM