我有一些查询在12c中运行良好很长时间,但是升级到18c后,它们开始花费更多的时间。 12c和18c DB的DB参数相同。我在OEM中可以看到的一件事是,估计行与实际行之间存在很多差异
我收集了使用表的统计信息,但问题仍然存在。
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都在表中的相同数据上运行。
答案 0 :(得分:1)
在过去的美好时光中,发明了一种称为Tuning by Cardinality Feedback的高级调整方法-作者(Wolfgang Breitling)的主要思想是比较基数估计的基数(行数)从数据源获得的实际行数的优化程序。如果这些数字相等或靠得很近,那么一切都很好,但相差很大则表明存在麻烦。例如,对于估计计数1,索引访问很好,但是索引访问对于实际计数1M来说是灾难性的情况。
此方法非常成功,以至于它在OEM查询概述中实现(您正在使用)。
请参见执行计划中的第4列和第7列:estimated rows
和actual 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)收集完整的表格/模式统计信息。