explain里面一些字段信息
优化过程
以下是针对两个sql语句结合业务场景进行优化的案例
业务sql一
sql语句
SELECT distinct(target_id) FROM ap_user_privilege where expired_time > '2020-04-07 11:56:57';
业务背景
主站的评论区调用xuser接口获取up主的 的大航海数量,接口qps 4w+(但是大部分请求中的up主都没大航海船员),所以服务定时每秒获取当下拥有有效身份的大航海的主播id放在内存中,接口判断请求ID不在内存中直接返回,这一步挡住了大部分的请求
慢查询分析
ixtest是(target_id,expired_time)的联合索引,这里优化器选择使用联合索引ixtest,而where条件是按照expired_time进行搜索的,没有用到前导列 target_id,所以进行了索引扫描,造成效率低
慢查询优化
1.根据业务场景,sql语句写的是合理的,没有优化空间
2.索引实际用到了索引扫描,没用到索引查找,索引有优化空间
根据sql语句,可以使用对expired_time建立单索引(实际表已经建立了这个索引,但是优化器没有使用)
使用expired_time单索引,相比较使用联合索引扫描行数少了大概30%
优化之后的语句为
SELECT distinct(target_id) FROM ap_user_privilege force index(expired_time) where expired_time > '2020-04-09 18:34:52';
20号上线之后慢查询已经没有了,问题解决
更好的方法:
目前强制使用单索引不会全索引扫描,但是会生成临时表,且需要回表,更好的办法是建立(expired_time,target_id)的联合索引,这样虽然还是会生成临时表,但是没有全索引扫描,不用回表,性能会大大提升
zhuanlan.zhihu.com/p/411359802
业务sql二
sql语句
SELECT id,skin_id,start_time,end_time,msg_status FROM ap_room_skin_config WHERE end_time <= '2020-04-07 12:09:00' OR start_time > '2020-04-07 12:09:00';
业务背景
获取所有失效的皮肤信息用来发送失效广播,每分钟执行一次
慢查询分析
1.全表扫描,没有使用索引
慢查询优化
语句优化
根据sql条件返回的数据几乎跟全表数据量相等,这样即使使用索引还是会hit到大部分索引范围,回表扫描大部分数据,所以应该在语句上优化
语句不合理的地方有几点
1.需求是获取所有当前过期的皮肤,但是查询的时候还用start_time 做判断条件,然后在业务里又去掉
2.获取截止到当前所有的过期皮肤,这样数据量会越来越大
优化的方法就是对过期时间做限制,查找两天内过期的皮肤,针对end_time做单索引
优化后的语句为
SELECT id,skin_id,start_time,end_time,msg_status FROM ap_room_skin_config WHERE end_time <= '2020-04-07 12:09:00' AND end_time => '2020-04-05 12:09:00';
参考