【MySQL】常見單表查詢索引優化總結

> 全值匹配我最愛

  1. 建立索引
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);
  1. 查看下列sql的Explian
 EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30  
 EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=4
 EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=4 AND emp.name = 'abcd'  

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

  • 最後一行因爲建的索引都用上了!快的一批
  • 結論:全值匹配我最愛,指的是查詢的字段按照順序在索引中都可以匹配到,索引都派上用場了
  1. 更換條件順序查看索引能否被應用

在這裏插入圖片描述

  • 結論:SQL中查詢字段的順序,跟使用索引中字段的順序沒有關係,有優化器用AND把條件連起來 會自動優化

> 最佳左前綴法則

  • 使用複合索引,需要遵循最佳左前綴法則,即如果索引了多列,要遵守最左前綴法則。指的是查詢從索引的最左前列開始並且不跳過索引中的列,跳了後面的索引會沒用上

在這裏插入圖片描述

  • 結論:帶頭大哥不能死,中間兄弟不能斷,過濾條件要使用索引必須按照索引建立時的順序,依次滿足,一旦跳過某個字段,索引後面的字段都無法被使用

> 索引列上做計算

  • 在索引列上做任何操作(計算、函數、(自動or手動)類型轉換),會導致索引失效而轉向全表掃描。
  1. 在查詢列上使用了函數
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE age=30;
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE LEFT(age,3)=30;

在這裏插入圖片描述

  • 結論:等號左邊無計算!等號左邊不能有計算。
  1. 在查詢列上做了轉換
create index idx_name on emp(name);
explain select sql_no_cache * from emp where name='30000';
explain select sql_no_cache * from emp where name=30000;

在這裏插入圖片描述

  • 結論:等號右邊無轉換!等號右邊不進行類型轉換

> 索引列上進行範圍查詢

explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=5 AND emp.name = 'abcd';
explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid<5 AND emp.name = 'abcd';

在這裏插入圖片描述

  • 總結:中間用了範圍查詢,會使後面的兄弟索引都失效,所以要將可能做範圍查詢的字段的索引順序放在最後

> 使用覆蓋索引

  1. 查詢列和索引列時,不要寫select *,即使要查50個字段就列50個字段
explain  SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30  and deptId=4 and name='XamgXt';
explain  SELECT SQL_NO_CACHE age,deptId,name  FROM emp WHERE emp.age=30  and deptId=4 and name='XamgXt';

在這裏插入圖片描述

> 使用不等於(!= 或者<>)

  1. 使用不等於(!= 或者<>)時,有時會無法使用索引導致全表掃描。因爲系統不知道哪個不等於,進行全表掃描比較
mysql> explain select SQL_NO_CACHE *  from emp where emp.age = 30 ;
mysql> explain select SQL_NO_CACHE *  from emp where emp.age != 30 ;

在這裏插入圖片描述

> is not null 和 is null

  1. 查看索引字段是否允許爲空
mysql> desc emp;
  1. 當字段允許爲Null的條件下
explain select * from emp where age is null
explain select * from emp where age is not null

在這裏插入圖片描述
結論:is not null用不到索引,is null可以用到索引。

> like的前後模糊匹配

  • 前綴模糊查詢會導致索引失效,最前面字母要確定下來
mysql> create index idx_name_emp on emp (name);
mysql> explain select * from emp where name like '%a' ;#索引失效
mysql> explain select * from emp where name like '%a%' ;#索引失效
mysql> explain select * from emp where name like 'a%' ;#索引不失效
mysql> explain select * from emp where name like '_a%' ;#索引失效

在這裏插入圖片描述

> 使用or

  1. OR查詢會導致索引失效
mysql> explain select * from emp where age = 30 or age = 40 ;

在這裏插入圖片描述

  1. 使用union all或者union來替代OR便不會失效
mysql> explain select * from emp where age = 30 union  select * from emp where age =40 ;

在這裏插入圖片描述

> 總結

  1. 建立索引index(a,b,c),判斷下列索引引用情況。
Where語句 索引是否被使用
where a = 3 Y,使用到a
where a = 3 and b = 5 Y,使用到a,b
where a = 3 and b = 5 and c = 4 Y,使用到a,b,c
where b = 3 或者 where b = 3 and c = 4 或者 where c = 4 N,大哥不在了
where a = 3 and c = 5 使用到a, 但是c不可以,b中間斷了
where a = 3 and b > 4 and c = 5 使用到a和b, c不能用在範圍之後,b斷了
where a is null and b is not null is null 支持索引 但是is not null 不支持,所以 a 可以使用索引,但是 b不可以使用
where a <> 3 不能使用索引
where abs(a) =3 不能使用 索引,做了計算
where a = 3 and b like ‘kk%’ and c = 4 Y,使用到a,b,c
where a = 3 and b like ‘%kk’ and c = 4 Y,只用到a
where a = 3 and b like ‘%kk%’ and c = 4 Y,只用到a
where a = 3 and b like ‘k%kk%’ and c = 4 Y,使用到a,b,c

> 口訣

全值匹配我最愛,最左前綴要遵守;

帶頭大哥不能死,中間兄弟不能斷;

索引列上少計算,範圍之後全失效;

LIKE百分寫最右,覆蓋索引不寫*;

不等空值還有OR,索引影響要注意;
在這裏插入圖片描述

用博客見證成長,用行動證明我在努力。
如果你有緣看到我博客,對你有幫助、喜歡博客內容,請“點贊” “評論”“收藏”一鍵三連哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章