SQL查询优化---单表使用索引及常见索引失效优化

如何避免索引失效

1、全值匹配

系统中经常出现的sql语句如下:

java 复制代码
 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'  

优化后

java 复制代码
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME)

建立索引前

索引后

2、最佳左前缀法则

如果系统经常出现的sql如下:

java 复制代码
 EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30   AND emp.name = 'abcd'   

或者

java 复制代码
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.deptid=1   AND emp.name = 'abcd'   

那原来的idx_age_deptid_name 还能否正常使用?

如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。

3、不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描

4、存储引擎不能使用索引中范围条件右边的列

如果系统经常出现的sql如下:

java 复制代码
 EXPLAIN SELECT  SQL_NO_CACHE * FROM emp WHERE emp.age=30 AND emp.deptId>20 AND emp.name = 'abc' ; 

那么索引 idx_age_deptid_name这个索引还能正常使用么?

如果这种sql 出现较多

应该建立:

java 复制代码
create index idx_age_name_deptid on emp(age,name,deptid)

效果

java 复制代码
# drop index idx_age_name_deptid on emp

5、mysql 在使用不等于(!= 或者<>)的时候无法使用索引会导致全表扫描

java 复制代码
 CREATE INDEX idx_name ON emp(NAME)
  EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE   emp.name <>  'abc' 

6、is not null 也无法使用索引,但是is null是可以使用索引的

java 复制代码
  UPDATE emp SET age =NULL WHERE id=123456;
   下列哪个sql语句可以用到索引
  EXPLAIN SELECT * FROM emp WHERE age IS NULL
  EXPLAIN SELECT * FROM emp WHERE age IS NOT NULL

7、like以通配符开头('%abc...')mysql索引失效会变成全表扫描的操作

8、字符串不加单引号索引失效

9、总结

java 复制代码
假设index(a,b,c)
      														
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
相关推荐
吾日三省吾码33 分钟前
JVM 性能调优
java
弗拉唐2 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi772 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
mqiqe2 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
工业甲酰苯胺2 小时前
MySQL 主从复制之多线程复制
android·mysql·adb
BestandW1shEs2 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师2 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球2 小时前
66 mysql 的 表自增长锁
数据库·mysql
Ljw...2 小时前
表的操作(MySQL)
数据库·mysql·表的操作