天天看点

管好统计信息,开启SQL优化之门

遇到执行效率低下的sql语句,对于dba而言无疑是家常便饭了,但如何快速优化,把它变成小菜一碟,则得看看咱们dba+社群联合发起人卢飞的经验之谈了。

专家简介

管好统计信息,开启SQL优化之门

卢飞

dba+社群联合发起人

oracle 10g ocp,6年oracle数据库维护经验,对oracle数据库管理、数据迁移,性能优化有着丰富的实战经验。目前专注于数据库技术及自动化运维方面的研究。

在dba的工作中,sql优化的工作量占工作很大的一块,我们在平时工作中也是这样,常常遇到一些执行效率低下的sql语句,而这些执行效率低下的sql,有的是业务系统刚刚上线的,有的是已经执行很久但因为执行环境变化而导致出现的。这里给大家分享一个sql的优化案例分析。

根据我们监控系统,发现线上oltp的一个核心业务数据库中有一条sql执行效率较慢。慢到什么程度?半小时执行278次,平均每次28秒,占用整个db资源的56%。oltp系统中,实在太慢了。

这里是sql执行的相关信息。

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

sql优化中,有很多人总是第一要看的就是执行计划,那么我们就看看这条sql的执行计划。下面可以看到单次执行3秒左右,成本为2,consistent gets较高,执行计划中也是走index range scan。

管好统计信息,开启SQL优化之门

其实单看上面的执行计划cost还是比较低的,sql优化中,有很多人总是第一要看的就是执行计划,但是看执行计划一定要结合结构信息,这里的结构信息就是表,索引等结构信息及数据分布信息。

我们先看sql语句吧。以下sql语句很简单,且在cn字段,c_date字段上都建有索引。

管好统计信息,开启SQL优化之门

表数据量约有3.6亿数据。

管好统计信息,开启SQL优化之门

在以上执行计划的基础上,根据对业务的理解,我的疑问是为什么不走cn索引?

这里其实可以根据谓词条件,各自查询 一下就能看到结果,根据cn查询到3条,而c_date条件查询出76w。走cn索引才对。

管好统计信息,开启SQL优化之门

这里也可以使用hint强制走cn索引看一下效果,使用hint强制走cn索引后执行时间变为毫秒级。

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

sql优化除了了解结构信息(表,索引),统计信息的准确性也很关键。

这里发现最后统计信息分析时间是5月份,相差了3个多月,所以统计信息是不正确的。

管好统计信息,开启SQL优化之门

统计信息不准确的原因?

最终发现oracle在10g版本中默认的gather_stats_job没有启动,这里启动默认的gather_stats_job,并单独收集一下表的统计信息。

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

收集完统计信息,这条sql的执行时间下降到毫秒级别,执行计划已经变为idx_rec_log_cn索引的range sacn,consistent gets从原来的19409  降低到了7。效果还是很明显。

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

同样的sql又慢了,现在的执行计划, 又开始走idx_c_log_date索引了,而且执行时间又回到了2秒, consistent gets变为10404。以下为执行计划:

管好统计信息,开启SQL优化之门

同样我们还是先检查统计信息是否正确,这里可以看到了统计信息又不正确了,但是我们发现gather_stats_job每天都能执行成功。这是为什么?

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

解决方法就是定义一个单表收集的job。

这也是为什么大表都单独定义收集统计信息的原因,面试过很多的同学,基本上说出直接原因的没有多少,都说是照着网上这么做的。

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

这里也可以看到相关的10053事件中的成本信息,具体可以参考以下的地址了解每个类型的含义。

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

最终我们在业务维护时间创建了cn+c_date联合索引后的执行计划,至今再无类似的sql性能问题。

管好统计信息,开启SQL优化之门
管好统计信息,开启SQL优化之门

<b>本文来自云栖社区合作伙伴"dbaplus",原文发布时间:2015-11-27</b>