在Oracle 12c中查看外部联接的性能问题

时间:2017-09-27 17:16:35

标签: sql oracle

我的两位客户最近升级为Oracle 12c 12.1.0.2。自升级以来,我在使用具有外连接的视图的查询中遇到显着的性能下降。下面是一个简单查询的示例,该查询在旧Oracle 11g 11.2.0.2数据库上以秒为单位运行,但在新12c数据库上需要几分钟。更令人困惑的是,这个查询在12c个数据库之一上运行得相当快(但速度不是很快),但在另一个数据库上运行得不是很快。一个12c数据库的性能非常糟糕,我所开发的报告无法使用。

我已经比较了11g和两个12c数据库之间的索引和系统参数,但没有发现任何显着差异。但是Execution Plans之间存在差异。在11g上,外部联接表示为VIEW PUSHED PREDICATE,但在12c上,它表示为HASH JOIN而没有PUSHED PREDICATE

当我在/*+ NO_MERGE(pt) PUSH_PRED(pt) */数据库的查询中添加提示12c时,性能会在几秒钟内完成。

在我们的Crystal Reports中添加提示不是一个选项(至少我不相信,也有几个报告),所以我希望我们能弄清楚为什么性能是在一个12c数据库上可以接受,但在另一个12c数据库上没有。

我和我的团队难以接受下一步的尝试,特别是为什么两个12c数据库之间的响应会如此不同。我们在12c中研究了几篇关于性能下降的文章,但没有任何内容特别适用于此特定问题。作为补充说明,使用表而不是视图的查询将在可接受的时间范围内返回结果。任何见解或建议都将不胜感激。

11g database

12c database

查询:

select pi.*
, pt.*
from policyissuance_oasis pi
, policytransaction_oasis pt
where 
pi.newTranKeyJoin = pt.polTranKeyJoin(+)
and pi.policyNumber = '1-H000133'
and pi.DateChars='08/10/2017 09:24:51'    -- 2016 data
--and pi.DateChars = '09/26/2016 14:29:37'  --2013 data
order by pi.followup_time

2 个答案:

答案 0 :(得分:0)

正如krokodilko所说,执行这些:

explain plan for 
select pi.*
, pt.*
from policyissuance_oasis pi
, policytransaction_oasis pt
where 
pi.newTranKeyJoin = pt.polTranKeyJoin(+)
and pi.policyNumber = '1-H000133'
and pi.DateChars='08/10/2017 09:24:51'    -- 2016 data
--and pi.DateChars = '09/26/2016 14:29:37'  --2013 data
order by pi.followup_time;
select * from table(dbms_xplan.display());

然后,您可能会在计划的底部看到这一点:

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

那里,

  

动态采样

概念应该是性能问题的关注中心(level = 2是默认值,范围在0-11之间)。

事实上,引入动态采样(DS)是为了提高优化器生成良好执行计划的能力。此功能已得到增强,并重命名为Dynamic Statistics in Oracle Database 12c。最常见的误解是DS可以用作优化程序统计信息的替代,而DS的目标是扩充optimizer statistics;当regular statistics不足以获得高质量的基数估算值时使用它。

对于串行SQL语句,dynamic sampling level

控制
  

optimizer_dynamic_sampling

参数但请注意,Oracle Database 12c Release 1 SQL plan directives的存在也可以在编译查询时启动dynamic statistics收集。这是自适应统计的一项功能,由数据库参数

控制
  

optimizer_adaptive_features(OAF)

<{1>}和

中的

  

optimizer_adaptive_statistics(OAS)

Oracle Database 12c Release 1中的

换句话说,从Oracle Database 12c Release 2(我们也在办公室使用db12.1.0.2)开始,如果通过将相关参数设置为{{1}来启用某些自适应功能,则将使用Oracle Database 12c Release 1 }}。

串行语句通常运行时很短,编译时的任何DS开销都会对整体系统性能产生很大影响(如果语句经常被硬分析)。对于与此配置文件匹配的系统,建议设置TRUEDS注意

  

你不应该改变系统而不是会话

)。

对于OAF=FALSE,建议使用默认的alter session set optimizer_adaptive_features=FALSE

Oracle Database 12c Release 2 onwards通常需要更多资源,因此在编译时通常需要投入额外的开销来寻找更好的OAS=FALSE

对于Parallel statements,您可以尝试手动设置SQL execution plan的值(假设没有相关的SQL计划指令)。如果我们针对具有并行属性集的较大表发出类似的查询样式,我们可以看到动态采样。

什么时候应该使用serial type SQL statements?当您知道由于复杂谓词而导致执行计划错误时,通常建议使用optimizer_dynamic_sampling。但不应该像我之前提到的那样是系统范围的。

何时使用dynamic sampling不是一个好主意? 如果查询编译时间需要尽可能快,例如,未经重复的DS查询,您可以通过多次执行来分摊编译的额外成本。

  

最后一句话,对于您的情况,设置可能是有益的   各个SQL的optimizer_adaptive_features参数为FALSE   陈述并看到获得的结果。

答案 1 :(得分:0)

我们发现了性能问题的原因。对于使用客户端Oracle服务器的主应用程序,DBA在系统级别更改了以下两个系统参数:

_optimizer_cost_based_transformation = OFF 
_optimizer_reduce_groupby_key = FALSE

当我们在会话级别将它们更改为以下内容时,连接2个视图的上述查询将在不到2秒的时间内返回结果:

alter session set "_optimizer_cost_based_transformation"=LINEAR;
alter session set "_optimizer_reduce_groupby_key" = TRUE;
COMMIT;

更改此参数对性能没有影响:

alter session set optimizer_adaptive_features=FALSE;
COMMIT;

我们还发现,对于更复杂的视图,更改以下参数可以进一步提高性能:

alter session set optimizer_features_enable="11.2.0.3";
COMMIT;