70-根因分析-oracle数据库突发性能问题,谁来背这个锅

    数据库突发性能问题,有时可能经过重启应用、从新收集统计信息、重启数据库等方法获得临时解决,可是,如何把故障根本缘由找到,避免故障再次发生,是问题获得完美闭环的一个关键步骤(固然,可以快速恢复业务也是很是关键的一环)。这也是为何不少对业务稳定性要求很是高的行业(好比金融、通讯、铁路、航空等)的数据库系统,购买oracle 售后高服(ACS)中的顶级服务SSC服务的一个主要缘由。算法


    根因分析的另一个重要性就是找到问题的责任方:运维、开发仍是数据库产品自身缘由(缺陷或是bug),有的问题是单方问题,有的可能几个方面都有。根因分析的结论会影响到部门考核,一个你们都信服的结论,可让背锅的一方心服口服。有时候让产品背锅,也是一个比较好的结局。sql

    

    见过网上有人分享一些故障处理的文章,虽然问题获得了解决,可是根因分析的结论倒是彻底错误的,好比有一个结论是index unique scan效率远远大于index range scan的案例,把一个数据库直方图局限性的问题,“有理有据”的解释成了索引扫描方式的问题,实属低级错误,误导观众。
数据库


    今天介绍的这个案例是一个学员发来的,请我对一个银行业务系统的SQL执行计划突变致使的性能问题作根因分析。我花了半小时左右对这个问题进行了分析,并给出了根因。性能优化

    

问题描述:微信

     2019-11-21 零时左右, 某重要业务SQL执行计划发生改变,执行效率严重降低。下面是采集到的sqlhc信息(数据库版本 11.2.0.4):oracle

根据上图信息能够看到,执行计划的cost变小了,效率却降低了几千倍。运维


    对于有经验的优化专家来讲,对于这个问题的第一反应就是谓词越界,按照这个思路,很快拿到证据(客户认为信息敏感,这里就不贴过多的细节),并给出根因。性能


根因分析:
优化


一、经过表的统计信息收集历史能够查到,11月20日晚,数据库对表作了自动统计信息收集。知识点1:工做日天天的22:00~02:00这个时段,系统会对须要从新收集统计信息的表,收集统计信息。
spa


二、知识点2:统计信息收集后的一段时间内,会对使用该表的相关SQL作硬解析。


三、知识点3:硬解析时,会发生绑定变量窥视。若是窥视到的绑定变量,超出了字段上统计信息的最大最小(通常是最大)值范围,就可能发生谓词越界。谓词越界就可能会出现索引选择错误,致使生成低效执行计划。


四、知识点4:真正的谓词越界通常发生在varchar2和number字段,日期字段虽然常常发生越界,可是系统对于日期类型字段的越界算法,有必定的容忍度,不会认为是真正的越界。这个sql发生越界的字段保存的数据是日期数据,可是使用的倒是number类型。这里面涉及到一个重要的开发规范相关内容:很是不建议用number或varchar2类型保存日期数据,规范作法是使用date类型。上面数据类型随意使用的作法是开发人员为了少敲几个字母的偷懒行为。由于按天查询时,date类型通常须要写两段范围条件,而number或varchar2类型,能够用一个等值条件便可完成,并且不用作to_date转换。这种偷懒的不规范作法,会给SQL性能带来较大的性能隐患。


五、知识点5:发生谓词越界后,数据库优化器在评估这个sql可使用的两个索引(都是以越界字段开头的组合索引)时,就不是常规的选择方式,而是选择leaf blocks较少的那一个,这个案例,leaf blocks较少的那个索引,刚好是低效的那一个。


下图上面是正常执行计划使用的高效索引,sql用到了索引的所有3个字段;下面是性能故障时执行计划使用的低效索引,sql只用到了JYRQ(number类型保存日期数据)一个字段:


下图#1对应的是上面的高效索引,#2对应上面的低效索引:


六、知识点6:sqlhc捕获到了sql后面的一些执行状况,不少使用的绑定变量已经再也不越界,并且系统的自适应游标(ACS)保持开启状态,为何ACS没能及时把执行计划调整回正常? 这里面又涉及到另外一个不规范的状况:绑定变量使用的数据类型是char,刚刚咱们提到字段使用的类型是number,优化器须要对绑定变量作to_number隐式类型转换,这种转换致使了ACS不生效。


七、知识点7:网上不少文章介绍说要关闭ACS,本人对这个说法不太赞同,这个案例,虽然ACS由于绑定变量类型不匹配没有生效,可是若是绑定变量使用的数据类型也是number,那么ACS就会生效,不会出现执行计划一错到底的状况:对于后面谓词不越界的状况,ACS还能及时调整回正常的执行计划。ACS在11g版本引入,开始时bug较多,到了11204版本,不少bug已经修复了,它起到的做用远远高于bug带来的一些小问题。


总结:

       经过以上分析,明显这个问题的根本缘由是开发人员使用不合适的数据类型保存日期数据,致使谓词越界很是容易发生;同时又使用了错误的绑定变量数据类型,让优化器的ACS功能失效。这个锅,彻底应该由开发人员来背。 可是,若是运维人员没有掌握上面的知识点,就没法分析出根因,那这个性能故障的锅就只能本身背着。

    这个sql,若是开发不作代码调整,相同故障仍有可能再次出现。临时解决方法是先使用sql profile绑定执行计划。


    更多案例与原理,本人在线下培训时会详细解读,12.28~12.29,2019年度最后一站,深圳见。

(完)

本文分享自微信公众号 - 老虎刘谈oracle性能优化(sql_tigerliu)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索