Mysql索引失效的场景分析

前言:

日常使用Mysql做一些业务时,发现很慢,跟踪日志返现是有慢查询语句,于是使用explain查看执行计划发现是没有使用到索引,一般这些情况都不是java框架导致的,一般框架里都会根据主键或者指定的条件去做简单的查询,复杂的查询都是通过sql原生写法来实现的,这种原生写法最容易产生类似这样的问题。

产生索引失效的场景

1、在sql中使用了函数,比如sum,count等内置函数,这种情况下即使where条件中使用到了索引也会索引失效。
2、在where语句中使用到了联合索引,但是使用的时候违反了最左原则。比如联合索引创建的时候为name,age 但是使用的时候确实where age = 1 and name = ‘cz’,这样会导致age的索引失效仅剩name索引。
3、在查询语句中一些字段的属性错误,比如name的字段定义为varchar,但是使用的时候条件写成了where name=cz,这样会导致mysql在真实查询的时候查找索引失败。
4、在sql中,如果使用模糊查询,但是字段为全模糊的比如:where name like ‘%cz%’,这种场景下索引是失效的,如果使用的语句为where name like ‘cz%’,那么这种索引反而是生效的。
5、在查询语句中出现了or,那么这个语句是不会使用到索引的

以上这些就是在写sql时经常遇到的一些索引失效的场景。

如果在java中,如果使用mybatis则需要手写sql,所以上面的场景需要格外注意。

其他慢sql调优手段

1、避免使用select * 多余的字段会消耗IO

2、使用索引

3、使用join替换in(看具体数据库来决定)

原因:分布式数据库exists效率低

4、join优化,如果执行计划中有使用Block-Nasted-Loop,需要根据实际情况增加缓存区的内存空间

5、大结果集的排序,如果结果集很大会涉及到文件排序(File-sort),需要根据业务拆分为小结果集再排序
6、在使用inner join时,如果优化器判断有误,这个时候要使用straght join来指定驱动表 hint方式

7、在查询语句中如果优化器使用索引不合理,需要使用FORCE INDEX指定索引。hint方式

8、delete/update关联操作,DML直接JOIN关联两张实体表,改成关联1张实体表和1个Join结果集

9、大事务拆分提交,如果一次事务太大可能会堵塞小事务的提交

10、使用group by进行分组查询时,默认会按照分组字段进行排序,也就是默认会在语句后面添加order by

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第20天,点击查看活动详情

你可能感兴趣的:(mysql,mybatis,数据库)