SQL优化

对于SQL优化,首先要思考如下问题:
SQL语句如何进行优化;SQL语句如何查看执行计划,关注哪些优化因素。

执行计划概览
这里写图片描述

id每个被独立执行的操作标识,标识对象被操作的顺序,id值越大,先被执行,如果相同,执行顺序从上到下
select_type查询中每个select 字句的类型
table被操作的对象名称,通常是表名,但有其他格式
partitions匹配的分区信息(对于非分区表值为NULL)
type连接操作的类型
possible_keys可能用到的索引
key优化器实际使用的索引
key_len被优化器选定的索引键长度,单位是字节
ref表示本行被操作对象的参照对象,无参照对象为NULL
rows查询执行所扫描的元组个数(对于innodb,此值为估计值)
filtered条件表上数据被过滤的元组个数百分比
extra执行计划的重要补充信息

可在mysql client 中输入 help explain 查看explain的帮助命令和语法,常用的用法是 explain extended(输出更多扩展信息)和explain format=json (json格式输出,可看到cost等信息)

========================
SQL优化步骤
第一步 查看执行计划:
在SQL前加上 explain extended,主要关注select_type(查询类型)、key(用到什么索引)、rows(查询执行扫描的元组个数)、extra(是否利用到排序、临时表等)。
由图可知:app_apply_step 表未用到索引,进行了全表扫描,app_mst和app_profile 两表利用了主键索引。
这里写图片描述
第二步 查看SQL涉及的表结构,此处主要查看app_apply_step 表:
show create table app_apply_step\G, 主要关注表的索引和where 条件中的字段类型。
可见 app_apply_step 表 is_exp 字段上无索引,且为tinyint类型。
这里写图片描述
第三步 思考可能优化的点:
看出索引区分度
先查看表 app_apply_step 字段某个字段is_exp的索引区分度 。
执行 select count()/(select count() from app_apply_step) from app_apply_step where is_exp =0 ; 如下图所示
is_exp 字段区分度约等于0,表明通过索引筛选非常高效。
执行建索引操作:
alter table app_apply_step add index idx_is_exp (is_exp);
这里写图片描述
第四步 重新执行SQL和查看执行计划:
执行计划用到了新建的索引,且执行时间从0.54秒到0.00秒(时间被四舍五入)。

这里写图片描述

总结SQL优化步骤
1. 查看执行计划 explain extended (数据库工具,命令行窗口)
2. 如果有告警信息,查看告警信息 show warnings;(命令行窗口)
3. 查看SQL涉及的表结构和索引信息
4. 根据执行计划,思考可能的优化点
5. 按照可能的优化点执行表结构变更、增加索引、SQL改写等操作
6. 查看优化后的执行时间和执行计划
7. 如果优化效果不明显,重复第四步操作

SQL优化常见问题

慢SQL常见问题解决办法
`where条件中索引列用!=(不等于) 和 not in 例如: select * from tb where a != 3``select * from tb where a > 3 and a < 3`
索引列函数转换,索引列参与计算 例如:select * from tb where a +3= 5; select * from tb where date(a) = ‘2018-03-23’;索引列不参与计算和函数转换select * from tb where a = 5 - 3;select * from tb where a = date(‘20180323 14:00:00’);
字段类型隐式转换,例如a字段为varchar字符型, select * from tb where a = test;where条件字段类型保持一致 select * from tb where a = ‘test’;
`表结构和索引设计不合理,复合索引中未使用前导列 例如:a、b、c为符合索引,select * from tb where b = 1 and c = 2;`索引尽量使用复合索引,并使用前导列,索引个数一般不超过5个 select * from tb where b = 1 and c = 2(将符合索引修改为b、c、a);
like/regexp %匹配符在左边 例如:select * from tb where a like ‘%test%’;符合业务逻辑,修改为:select * from tb where a like ‘test%’;
大数据量分页问题,M>=10000, 例如:select * from tb limit M,N改成基于主键查询,SELECT * FROM tb WHERE ID > =(select ID from tb limit M, 1) limit N

感谢公司MBA关于SQL优化的讲解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值