暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

性能优化之oracle SQL执行计划异常诊断一例

IT那活儿 2020-07-15
678

亲爱滴伙伴们,本萎砖家又来了。这次咱说说SQL加了并行hint,但并行却跑不起来的小案例。这事儿的起因是应用侧一哥们儿反馈一个存储过程平时只要1个小时就可以跑完,这次跑了4个多小时还望不到头儿,找过来需要友情协助。


干运维的都是苦命孩子,大家能互相帮衬的就互相帮衬点儿,你说要是找我借个十块八块钱的话,我也帮不上忙。这手到擒来的活儿,还是义不容辞的撸起袖子,开始排查问题原因。


根据这哥们儿提供过来的sql文本,在库里找到了对应的会话及正在运行的SQL。查看session相关属性信息,确定与跟之前运行的时间相差很大(看来这大兄弟也是实在人,硬是多扛了3个多小时才喊痛)。看到这个差别第一反应是执行计划的相关原因导致,核实执行计划后,果然和怀疑的一样,执行计划一直在变。


既然执行计划总是在变,那咱就看看这2个执行计划的区别在哪儿?

执行计划显示SQL是一个insert....select....语句,SQL中有/*+APPEND ENABLE_PARALLEL_DMLPARALLEL("a",8)+*/开启PDML并行的hint,其中低效的执行计划显示DML并行无效(PDMLdisabled because object is not decorated with parallelclause)。


我们继续分析执行计划发现高效执行计划在预插入数据的目标表insert及其索引维护动作均开启了并行,但低效执行计划没有。


问题点出现了:

  • 为啥ENABLE_PARALLEL_DMLhint有时候起作用,有时候就失效了呢?

  • PDMLdisabled because object is not decorated with parallel clause?

  • 为啥会报对象没有用parallel子句修饰?难道是hint写错了?


顺着这个思路继续查看sql书写规范,果然有发现,别名上多了双引


去掉双引号测试一切回归正常:


其实,这里有一个更稳妥的老司机的做法可以防止hint写错影响并行的开启,使用会话级别打开并行:

  • altersession force parallel query parallel 16;

  • altersession force parallel dml parallel 16;

该方式就算hint写错了也没关系,照样会走并行。


总结:

从这个例子我们可以看到一个小小的双引号竟然可以导致parallel hint间隙性失效,真是应了那句老话儿,一粒老鼠屎坏了一锅汤。所以说工作中规范很重要。好了,本次分享到此结束,咱下回分享再见。

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论