MySQL索引一些常用案例


索引案例分析

  • 先創建一些假數據:
create table test03(
id int primary key not null auto_increment,
c1 char(10),
c2 char(10),
c3 char(10),
c4 char(10),
c5 char(10)
);

insert into test03(c1,c2,c3,c4,c5)values('a1','a2','a3','a4','a5');
insert into test03(c1,c2,c3,c4,c5)values('b1','b2','b3','b4','b5');
insert into test03(c1,c2,c3,c4,c5)values('c1','c2','c3','c4','c5');
insert into test03(c1,c2,c3,c4,c5)values('d1','d2','d3','d4','d5');
insert into test03(c1,c2,c3,c4,c5)values('e1','e2','e3','e4','e5');
  • 創建索引:
create index idx_test03_c1234 on test03(c1,c2,c3,c4);
  • 根據索引進行判斷索引是否失效
  • order by
explain select * from test03 where c1='a1' and c2='a2' and c3='a3' and c4='a4';
# and連接每個索引字段,順序是c1,c2,c3,c4.當前最佳匹配,所有索引都用上,並遵循最左前綴,當然精度越高,key_len越高,代價越大。

explain select * from test03 where c1='a1' and c2='a2' and c4='a4' and c3='a3';
# 雖然查詢條件順序發生改變,但c1,c2,c3,c4都能用到索引查詢。因mysql內部會做優化。

explain select * from test03 where c4='a4' and c3='a3' and c2='a2' and c1='a1';
# 與上例一樣結論,and連接可忽略順序。sql內部會做優化

explain select * from test03 where c1='a1' and c2='a2' and c3>'a3' and c4='a4';
# c1,c2能用到索引進行查找,因c3是范圍條件,索引只用到排序,導致在c3處斷裂,這樣c4用不到索引

explain select * from test03 where c1='a1' and c2='a2' and c4>'a4' and c3='a3';
# 都能用到索引,首先mysql 根據and連接,內部優化順序,只不過是c1,c2,c3用索引是用來查找, 而c4用索引進行排序

explain select * from test03 where c1='a1' and c2='a2' and c4='a4' order by c3;
# 用到c1,c2索引進行查找,c3也用到了索引只不過是用來排序,並c3沒有統計到執行計划中,c4沒有用到索引

explain select * from test03 where c1='a1' and c2='a2' order by c3;
# 與上例一樣。根據跟上例對比,可以發現c4的索引並沒有起效。原因c3索引用於范圍查找,導致c4無法利用索引。

explain select * from test03 where c1='a1' and c2='a2' order by c4;
# c1,c2使用索引進行查找,但是中間跳過c3直接使用c4進行排序,導致sql內部使用filesort進行排序。

explain select * from test03 where c1='a1' and c5='a5' order by c2,c3;
# 因為c5沒有創建索引,所以c5沒有用到索引。而c1使用索引進行查找,c2,c3使用索引進行排序

explain select * from test03 where c1='a1' and c5='a5' order by c3,c2;
# 與上例不同Extra出現filesort ,c3,c2順序顛倒,sql內部無法識別,所以sql內部使用filesort進行排序

explain select * from test03 where c1='a1' and c2='a2' order by c2,c3;
# c1,c2用到索引查詢。c2,c3用來排序。

explain select * from test03 where c1='a1' and c2='a2' and c5='c5' order by c2,c3;
# 與上例結果一樣, c5並不會影響結果

explain select * from test03 where c1='a1' and c2='a2' and c5='c5' order by c3,c2;
# 通過這么多order by案例,一般情況order by沒有按照索引順序排序,會出現filesort。但是,c2在前面索引查找已經是const常量,索引不會出現filesort
  • group by
explain select * from test03 where c1='a1' and c4='a4' group by c2,c3;
explain select * from test03 where c1='a1' and c4='a4' group by c3,c2;
# 首先知道的是分組之前必須進行排序。
# 第一個例子:使用了c1索引,索引未完全失效。
# 第二個例子:group by 后索引順序顛倒,出現了filesort和temporary,產生臨時表。
  • 小結:索引有查找和排序兩個功能,一般order by 是進行范圍排序,group by基本上分組之前必進行排序,會有臨時表產生。

  • like

explain select * from test03 where c1='a1' and c2 like 'kk%' and c3='c3';
# 用到了c1,c2,c3,有人會疑問c2使用索引為范圍排序,會導致c3失效,但是c2以常量開頭,這樣不會導致c3索引失效。

explain select * from test03 where c1='a1' and c2 like '%kk' and c3='c3';
# 只用到了c1索引。c2以%開頭失效,c3根本沒有被輪到

explain select * from test03 where c1='a1' and c2 like 'k%kk%' and c3='c3';
# 用到了c1,c2,c3 與案例一樣。

  • 案例總結:
    • 對於單鍵索引,盡量選擇針對當前查詢過濾性更好的索引。
    • 在選擇組合索引的時候,當前查詢中過濾性最好的字段在索引字段順序中,越靠前越好。
    • 在選擇組合索引時候,盡量選擇可以能夠包含當前查詢中where字句中更多字段的索引。
    • 盡可能通過分析統計信息和調整查詢的寫法來達到選擇合適索引的目的


免責聲明!

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



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