查询运行缓慢后升级到18c

时间:2019-12-04 14:27:06

标签: oracle

我有一些查询在12c中运行良好很长时间,但是升级到18c后,它们开始花费更多的时间。 12c和18c DB的DB参数相同。我在OEM中可以看到的一件事是,估计行与实际行之间存在很多差异

enter image description here

我收集了使用表的统计信息,但问题仍然存在。

dbms_stats.gather_table_stats(ownname => USER, tabname => 'XYZ',
method_opt=> 'for all indexed columns size skewonly', granularity => 'ALL', degree => 8 ,
cascade => true,estimate_percent => 15);

两个DB都在表中的相同数据上运行。

2 个答案:

答案 0 :(得分:1)

过去的美好时光中,发明了一种称为Tuning by Cardinality Feedback的高级调整方法-作者(Wolfgang Breitling)的主要思想是比较基数估计的基数(行数)从数据源获得的实际行数的优化程序。如果这些数字相等或靠得很近,那么一切都很好,但相差很大则表明存在麻烦。例如,对于估计计数1,索引访问很好,但是索引访问对于实际计数1M来说是灾难性的情况。

此方法非常成功,以至于它在OEM查询概述中实现(您正在使用)。

请参见执行计划中的第4列和第7列:estimated rowsactual rows。自下而上检查差异,从底部开始的第三行已经有1到1M的巨大差异-这是您的第一个问题

您必须检查此行的 access filter 谓词,并调查为什么会产生此基数不匹配(请参阅here,了解如何获得完整的解释计划以及谓词信息。

在大多数情况下,原因是缺少或优化器对象统计信息不正确。

当然,升级时可能会更改基数估计算法,并且您必须调整统计信息,这在旧版本中还不错-让我们知道!

答案 1 :(得分:0)

长期运行的过程有多个查询,升级影响了其中几个查询。

以下步骤解决了该问题

1)收集最新统计信息

最初,我在升级后收集了

的统计信息
dbms_stats.gather_table_stats(ownname => USER, tabname => 'XYZ',
method_opt=> 'for all indexed columns size skewonly', granularity => 'ALL', degree => 8 ,
cascade => true,estimate_percent => 15);

从William的评论中,我进一步研究了method_opt参数,在这里选择opt'for all indexed column size skewonly'的方法不是正确的策略,因此我改用了Oracle的默认值'F FOR ALL COLUMNS SIZE AUTO',并且还删除了Estimate_percent以便选择默认值

dbms_stats.gather_table_stats(ownname => USER, tabname => 'XYZ',
granularity => 'ALL', degree => 8 ,
cascade => true);

2)另一个查询使用的是内联视图,并且该视图已嵌入在冗长/复杂的查询中,这表明从Temp空间读取时出现滞后,不确定这是否是由于某些参数更改还是由于某些算法更改使用18c,但为了绕过此问题,已将查询分解为较小的块,并使用全局临时表插入了内联视图的数据作为第一步,然后代替内联视图从GTT读取数据,这解决了运行缓慢的问题。

如果您看到查询缓慢/计划翻转发布了Oracle升级,我可以建议的两个主要步骤是 a)检查参数设置,是否可能在数据库中发生任何明显的参数更改,从而导致优化器以不同的方式工作

b)收集完整的表格/模式统计信息。