概述
今天主要分享一条sql优化的大致过程,仅供参考。
ps:其实还有个更复杂的sql,大概400行,最后通过缩小结果集实现优化,但是不好写就不放了..
zabbix监控
从监控可以发现在在9点时内存和CPU同时飙升,检查数据库sql发现是一条sql导致。
问题sql
这个定位直接select * from information_schema.proceslist where state!=''就看到了,所以就直接放问题sql了。
其中t_bms_order_base_line表数据有14492760条,执行删除sql的时候走全表扫描,导致一直卡着。
explain select * from t_bms_order_base_line
where exists (select 1
from t_bms_order_base
left join t_bms_order_base_temp
on t_bms_order_base_temp.id=t_bms_order_base.id
where t_bms_order_base.id=t_bms_order_base_line.order_base and t_bms_order_base.is_cost='0'
)
查看执行计划
很明显删除大表的时候走了全表扫描
检查表上的索引发现order_base字段已建立了相关索引,且order_base区分度为0.2428也是没问题的。(建议大于0.1)
通过exists改写sql
改写后发现这里也没用上索引
explain select * from t_bms_order_base_line
where exists (select 1
from t_bms_order_base
left join t_bms_order_base_temp
on t_bms_order_base_temp.id=t_bms_order_base.id
where t_bms_order_base.id=t_bms_order_base_line.order_base and t_bms_order_base.is_cost='0'
)
通过联合join改写sql
考虑join改写的方式,测试发现已经走相关的索引,且删除只耗时20秒。
DELETE t_bms_order_base_line
FROM
t_bms_order_base_line
INNER JOIN ( SELECT t_bms_order_base.id FROM t_bms_order_base_temp LEFT JOIN t_bms_order_base ON t_bms_order_base_temp.id = t_bms_order_base.id WHERE t_bms_order_base.is_cost = '0' ) b ON t_bms_order_base_line.order_base = b.id
后面会分享更多devops和DBA方面内容,感兴趣的朋友可以关注下~ 对了,在sql上需要优化的也可以VX我,一起探讨..
ps:因为懒所以没怎么看头条,所以很多评论和私信都不会及时回复..