1. 程式人生 > 其它 >MySQL 索引失效的幾種型別以及解決方式

MySQL 索引失效的幾種型別以及解決方式

索引失效的情況有哪些?

  1. 索引列不獨立
  2. 使用了左模糊
  3. 使用 or 查詢部分欄位沒有使用索引
  4. 字串條件沒有使用 ''
  5. 不符合最左字首原則的查詢
  6. 索引欄位沒有新增 not null 約束
  7. 隱式轉換導致索引失效

索引列不獨立是指 被索引的這列不能是表示式的一部分,不能是函式的引數,比如下面的這種情況

select id,name,age,salary from table_name where salary + 1000 = 6000;

salary 列被使用者表示式的計算了,這種情況下索引就會失效,解決方式就是提前計算好條件值,不要讓索引列參與表示式計算,修改後 sql 如下

select id,name,age,salary from table_name where salary = 5000;

索引欄位作為函式的引數

select id,name,age,salary from table_name where substring(name,1,3)= 'luc';

解決方式是什麼呢,可以提前計算好條件,不要使用索引,或者可以使用其他的 sql 替換上面的,比如,上面的sql 可以使用 like 來代替

select id,name,age,salary from table_name where name like 'luc%';

使用了左模糊

select id,name,age,salary from table_name where name like '%lucs%';

平時儘可能避免用到左模糊,可以這樣寫

select id,name,age,salary from table_name where name like 'lucs%';

如果實在避免不了左模糊查詢的話,考慮一下搜尋引擎 比如 ES

or 查詢部分欄位沒有使用索引

select id,name,age,salary from table_name where name ='lucs' and age >25

這種情況,可以為 name 和 age 都建立索引,否則會走全表掃描。

字串條件沒有使用 ''

select id,name,age,salary from table_name where phone=13088772233 

上面的這條 sql phone 欄位型別是 字串型別的,但是沒有使用 '13088772233 ', SQL 就全表掃描了,所以字串索引要使用 ‘’

select id,name,age,salary from table_name where phone='13088772233 '

不符合最左字首原則的查詢

例如有這樣一個組合索引 index(a,b,c)

select * from table_name where b='1'and c='2'
select * from table_name where c='2'

// 上面這兩條 SQL 都是無法走索引執行的

最左原則,就是要最左邊的優先存在,我不在的話,你們自己就玩不動了,除非你自己單獨創立一個索引,下面這幾條 SQL 就可以走索引執行

select * from table_name where a = 'asaa' and b='1'and c='2'
select * from table_name where a = 'asda' and b='1231' 
// 上面這兩條是走索引的,但是下面這條你覺得索引應該怎麼走,是全部走,還是部分走索引?
select * from table_name where a = 'asda' and c='dsfsdafsfsd' 

索引欄位沒有新增 not null 約束

select * from table_name where a is null;
// 這條sql就無法走索引執行了,is null 條件 不能使用索引,只能全表掃描了
// mysql 官方建議是把欄位設定為 not null 

所以針對這個情況,在mysql 建立表字段的時候,可以將需要索引的字串設定為 not null default '' 預設空字串即可

隱式轉換

關聯表的兩個欄位型別不一致會發生隱式轉換

select * from table_name t1 left join table_name2 t2 on t1.id=t2.tid;
// 上面這條語句裡,如果 t1 表的id 型別和 t2 表的tid 型別不一致的時候,就無法
// 按索引執行了。
// 解決方式就是統一設定欄位型別。