我的两位客户最近升级为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
中研究了几篇关于性能下降的文章,但没有任何内容特别适用于此特定问题。作为补充说明,使用表而不是视图的查询将在可接受的时间范围内返回结果。任何见解或建议都将不胜感激。
查询:
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
答案 0 :(得分:0)
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
收集。这是自适应统计的一项功能,由数据库参数
<{1>}和中的optimizer_adaptive_features(OAF)
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
开销都会对整体系统性能产生很大影响(如果语句经常被硬分析)。对于与此配置文件匹配的系统,建议设置TRUE
(DS
注意
你不应该改变系统而不是会话
)。
对于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;