首页 存档 技术 查看内容

记一次区域DB突发变慢的SQL优化博弈

2018-3-30 13:00 |来自: 互联网 369 0

摘要: 作者介绍 黄浩,现任职于中国惠普,从业十年,始终专注于SQL。十年一剑,十年磨砺。3年通信行业,写就近3万条SQL;5年制造行业,遨游在ETL的浪潮;2年性能优化,厚积薄发自成一家。 谨以该优化方案,纪念里约奥运会 ...



作者介绍

黄浩,现任职于中国惠普,从业十年,始终专注于SQL。十年一剑,十年磨砺。3年通信行业,写就近3万条SQL;5年制造行业,遨游在ETL的浪潮;2年性能优化,厚积薄发自成一家。


谨以该优化方案,纪念里约奥运会中国女排4强赛战胜巴西女排。


2016年8月17日,这本是一个平常的日子,如果硬是要与其他重要事件关联在一起,那就是里约奥运会了。或许是08北京奥运的疯狂激奋严重透支了国人的奥运热情,而产生了审美疲劳;也或许是在经过几代人的奋发图强,国人不再需要奥运金牌数量来证明自我,从而看淡了奥运赛场的剑拔弩张人喊马嘶。而与我而言,是由于工作、家庭的缘故,无暇奥运。

中午小憩后,将醒未醒中打开电脑,一封未读邮件让我瞬间惊醒睡意全无:




从邮件内容看,透露了如下几个信息:

  1. 是突然变慢:也就是说在此之前是没有性能问题的,性能问题是突然性的;

  2. 代码没有改动:也就是说本次性能变慢并非代码变更引起;

  3. 区域慢,中心不慢:也就是说同样的SQL,在不同的DB服务器上性能表现不一样。


我首先想到的是执行计划走偏导致的,因为第一点和第二点很符合执行计划走偏导致性能问题的表象。于是,我找到开发人员拿到了SQL,SQL如下:




通过SQL TEXT,我找到了SQLID,从ASH获得的信息如下:




从ASH中我们发现:执行计划很稳定,并没有发生“走偏”的异象。

难道是数据量发生了变化,导致了性能的突然变慢?

正当我计划咨询相关人员的时候,ESPACE弹出了消息,是多人讨论组,里面的人员名单中有开发人员、SE及性能测试人员。经过一番你来我往的讨论后,信息归纳如下:


  1. 这是个查询基础数据的SQL,数据量并没有发生变化

  2. 由于是基础数据,原始数据都是存放在中心库,各个区域库是通过OGG同步,因此,中心库和个区域库的数据量是一样的

  3. 经确认,所有的区域库都变慢了,而中心库则很好很快;

  4. 在变慢之前,没有做任何的代码变更

  5. 由于一线业务对首页加载突然变慢很不适应,影响面非常广,因此勒令务必在当天予以解决

  6. 同样的代码,同样的表,同样的数据量,为何中心和区域性能相差这么大?因此,SE要求在不修改代码的基础上解决该问题,很明显,他认为这不是代码的问题。


在上述6条信息中,第5条信息是最要命的,我瞄了下屏幕右下方,发现当时已是14:26,离下班只有3个半小时。而至于第6条的要求,我心里面已经有了解决方案的腹稿。

在排除了执行计划走偏、数据量变化的因素后,我把目光瞄准了“中心快,区域慢”这一现象。于是我决定对比下中心和区域的执行计划,看是否一致?


区域执行计划:



中心执行计划:




果真,两个执行计划有明显的偏差:




而在差异中,最扎眼的莫过于执行计划的第20行,区域环境是UNOIN ALL,中心库是UNION ALL PUSHED PREDICATE。即中心库对VIEW做了谓词推入,而区域库则没有,而这个视图就是臭名昭著的该死的BAS_PROJECT_ALL_V。

由于SQL返回的结果集很少,一般都是在50条以内,所以对该视图进行PUSHED PREDICATE是最优方案。从执行计划中的COST中也可以看出,中心库在VIEW上的COST消耗为225,而区域库的消耗竟达到了15322,相差两个数据量级,套用对中国足球的评语“想不输都难”,区域库“想不慢都难”呀。

区域库和中心库执行计划的差异是我想要的结果,因为有了这个结果,才能实施我的方案:绑定执行计划,即将中心库的执行计划绑定到区域库。我将临时方案与SE沟通后,SE同意先通过绑定执行计划的方式解决一线业务的性能之需。于是我将SQLID及PLAN_HASH_VALUE发给DBA,由DBA通过SQL_PROFILE的方式将中心库的执行计划绑定到了区域。

至此,按照正常的剧情设计,接下来的画面应该是这样的:通过绑定执行计划,区域的性能得到飞速提升,临时方案不战而屈人之兵,兵不血刃的完成了优化,开发人员、SE、测试人员、一线业务人员都皆大欢喜。而接下来的就可以有充裕的时间来分析区域库不进行谓词推入的原因,从而从根本上解决性能问题。

但是,生活终究是没有剧本的。

当DBA通过SQL_PROFILE完成绑定后,测试人员则反馈:还是不行,感觉更慢了……原来是4-5秒,现在出不来。什么情况?剧情也太反转了。DBA懵了、SE懵了、我也懵了:没道理呀!!!!DBA赶紧回滚,我再次去到区域库,当我看到执行计划的时候,我和我的小伙伴惊呆了,执行计划中明明显示是绑定了执行计划的:



但是,谓词却没有被推入。绑定执行计划的方案最终以失败告终。经过这一番折腾,时针转到了4点半的方向,仍然是套用评论中国足球的一句话“留给中国队的时间不多了”。

又回到问题的本质,影响Oracle执行计划的是COST计算,而COST的计算基础则是表的统计信息、索引、数据分布等因素。因为区域的数据是通过OGG从中心库同步过来的,因此数据分布应该是一致的,否则就不是性能问题,而是更严重的功能问题了。我收集了该SQL涉及到的所有表对象,通过对比两套环境,发现区域的统计信息和中心基本上是一致的;而索引也是一致的。为了确保万一,DBA手工对这些表对象进行了一次统计信息收集。而Oracle依旧无动于衷,固执的抛弃了“谓词推入”,即便是在SQL中加上/* push_pred(p)*/hint。

情况变得越来越复杂,越来越糟糕,越来越不可控。

就在百思不得其解,一筹莫展之际,DBA发来了一封邮件,内容如下:




意思是说:造成中心和区域执行计划不一致的原因是Oracle的版本不一致,针对视图这种场景,中心库的版本高,支持谓词推入;而区域库的版本低,不支持谓词推入。

这封邮件并没有解决问题,但是却价值千金,因为它证明了:在区域库现有版本的基础上,很难通过后台技术(比如绑定执行计划)来完成优化。

SE也无奈的接受了DB的建议:从SQL上进行优化。而此时,时针又顺时针方向移动了30°,也就是说我必须得在半小时内完成SQL优化。

看着这个SQL,有种似曾相识的感觉,一打听,才知道上次也优化过一个类似的SQL(详见 声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除


路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部