相同的执行计划,正常的SQL竟然查询不出结果,直接把DB干down了!
1.故障现象
最近生产环境一个正常的SQL,突然查询不出结果,平时也就1分多钟正常执行,通过调查发现,相同的执行计划,SQL的效率尽然相差百倍!
2.故障排查
继续通过AWR报告分析,发现这个SQL为一个视图,view的查询体达到了1000行,和业务人员沟通后发现,此SQL为定时调度的一个任务,查询的是最近3个月的数据并汇总,而且近期试图并没有做过任何修改。这个SQL的定时任务运行了1年了,从来没有出现过问题,而这次IO字节尽然耗费了800GB左右,直接不出结果。
根据经验判断,计划相同执行时间差距大,一般是出现了查询条件skew导致的,并切这个查询view的操作没有带条件,应该是用了中间表或临时表,相当于是过滤条件,那么统计信息的准确性就至关重要,通过排查发现,因为这个SQL的性能问题是发生在月初,很多分区表刚刚跨了分区,统计信息并没有及时收集。
3.故障处理
3.1 统计信息收集
--针对跨月分区1号凌晨4点定时收集统计信息
exec dbms_stats.gather_table_stats(
ownname => 'SCOTT',
tabname => 'T1',
partname => 'P1',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size repeat',
degree => 15, 收集时候的并行度
granularity=> AUTO,
cascade =>true
no_invalidate=> false
force=>false
)
3.2 关闭CBO自动优化
_optimizer_use_feedback参数默认是TRUE,
即开启Cardinality Feedback,
FALSE为关闭Cardinality feedback。alter system set "_optimizer_use_feedback"=false;
对于执行计划中,在note部分如果有“cardinality feedback used for this statement”,表示使用了基数反馈(Cardinality Feedback)。
基数反馈(Cardinality Feedback)是Oracle 11.2开始Oracle有了一种新的特性,Cardinality Feedback是一个优化器自动优化的过程,优化器会自动修正重复执行的查询的执行计划。对于一些复杂的查询,比如多字段条件,字符串范围比较,数据SKEW等等,以及缺乏统计信息,优化器可能不能够产生一个完全准确的基数估计, 如丢失或统计数据不准确,或复杂的谓词的基数估计,cardinality feedback 就是基于这一原因而产生的。
4.总结
SQL性能优化涉及多个方面,包括查询语句的优化、索引的使用、数据表的设计和硬件配置等,定位根因才能彻底点解决!