在某客户现场发现了一个执行了很长时间(15.8小时)仍未执行完的SQL,而且SQL使用了8个并行进程:
SQL代码如下:
SELECT /*+ PARALLEL(a,8)*/ count(: "SYS_B_0")
FROM so1.ins_srv_attr_780 a
WHERE a.offer_inst_id IN
(
SELECT /*+parallel(b,8)*/ b.offer_inst_id
FROM so1.ins_offer_780 b
WHERE b.offer_type = : "SYS_B_1"
) AND
a.prod_srv_relat_id NOT IN
(
SELECT c.prod_srv_relat_id
FROM so1.ins_prod_ins_srv_780 c
);
SQL包含一个IN和一个NOT IN,执行计划中not in的filter步骤效率低,而且这一步还漏写了并行hint(不是主要问题)。为什么优化器会选择这样低效的执行计划?
客户修改了多个隐含参数:
OPT_PARAM('_optimizer_use_feedback' 'false')
OPT_PARAM('_optimizer_join_factorization' 'false')
OPT_PARAM('_optimizer_enable_density_improvements' 'false')
OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
OPT_PARAM('_bloom_pruning_enabled' 'false')
OPT_PARAM('_gby_hash_aggregation_enabled' 'false')
OPT_PARAM('_optimizer_join_elimination_enabled' 'false')
OPT_PARAM('_optimizer_extended_cursor_sharing' 'none')
OPT_PARAM('_bloom_filter_enabled' 'false')
OPT_PARAM('_optimizer_squ_bottomup' 'false')
经过执行排查,发现其中的罪魁祸首就_optimizer_squ_bottomup:
我们来看看这个参数为默认TRUE的时候SQL的执行情况(顺便修正了并行写法问题):
SELECT /*+ PARALLEL(8) OPT_PARAM('_optimizer_squ_bottomup' 'true') */ count(1)
FROM so1.ins_srv_attr_780 a
WHERE a.offer_inst_id IN
(
SELECT b.offer_inst_id
FROM so1.ins_offer_780 b
WHERE b.offer_type = 'OFFER_PLAN_BBOSS'
) AND a.prod_srv_relat_id NOT IN
(
SELECT c.prod_srv_relat_id
FROM so1.ins_prod_ins_srv_780 c
);
效果直接看下图:
系统参数,尤其是隐含参数,在没有遇到bug的情况下,一般不建议修改,这个案例就是非常明显的一个教训。
本文分享自 老虎刘谈oracle性能优化 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!