一:优化建议:
1、针对SQL语句的优化
1.1、查询语句中尽量不要使用 *
1.2、尽量减少子查询,使用关联查询(left join,right join,inner join)替代,尽量减少对表的访问次数
1.3 、in 和 exists 效率对比
有一种说法,说exists性能比in要好,其实不全然。哪个性能更好,需要看具体的需求场景
1)子表数据量比外表数据量少,使用in。
2)子表数据量比外表数据量大,使用exists。
3)子表与外表数据量大小差不多,用in与exists的效率相差不大。
1.4、 not in 和 not exists
使用not in 会内外表都全表扫描,使用not exists还能用上内表(子表)的索引。所以,一定建议使用not exists
1.5、建表的时候能使用数字类型的字段就使用数字类型(type,status...),数字类型的字段作为条件查询比字符串的快
1.6、合理的增加冗余的字段(减少表的联接查询)
1.7、使用where子句替换having
2、使用索引时SQL的优化
2.1、使用索引的列尽量不要使用not(条件),也尽量不要使用is null或者 is not null
原因:使用not后,索引失效,数据库会将这列数据全扫描。
2.2、使用索引的列尽量不要使用计算操作
2.3、针对多个索引列出现在where子句的or条件下时:使用union比or效率高:(使用or时,这些列忽略了索引)
2.4、一个索引,加在一个表中多列上, 此时如果where子句出现了这几列,此时起作用的索引列是靠前的列。(MySQL最佳左前缀法则)
2.5、order by后面使用索引列时,不要使用约束为null的列,这会使索引失效
2.6、 distinct 去重复效率低下: 可以通过exists实现
如:SELECT DISTINCT dep_name FROM dep , emp WHERE dep.dep_id=emp.dep_Id(效率低)
SELECT dep_name FROM dep WHERE EXISTS(SELECT dep_id FROM emp WHERE emp.dep_id=dep.dep_id) (效率高)
2.7 、使用>= 替代>
如: select * from emp where dep_id>=10(效率高,因为depto直接定位到10,效率高)
select * from emp where dep_id>9 (先定位到9 ,然后还要排除9 ,效率低)
2.8、尽量在group by前面将数据过滤掉
如:select job,avg(sal) from emp where job=’程序员’group by job (效率高)
select job,avg(sal) from emp group by job having job=’程序员’(效率低)
二:MySQL执行计划
三、MySQL索引失效的情况
1、不遵守最佳左前缀法则(带头索引不能死,中间索引不能断)
如果索引了多个列,要遵守最佳左前缀法则。指的是查询从索引的最左前列开始 并且 不跳过索引中的列。
2、不要在索引上做任何操作(计算、函数、自动/手动类型转换),不然会导致索引失效而转向全表扫描
3、mysql存储引擎不能继续使用索引中范围条件(bettween、<、>、in等)右边的列
4、尽量使用覆盖索引(只查询索引的列(索引列和查询列一致)),减少select *
5、索引字段上使用(!= 或者 < >)判断时,会导致索引失效而转向全表扫描
6、索引字段上使用 is null / is not null 判断时,会导致索引失效而转向全表扫描
7、索引字段使用like以通配符开头(‘%字符串’)时,会导致索引失效而转向全表扫描,可以使用覆盖索引
8、字符串不加单引号索引失效
9、少用or,用它来连接时索引会失效