Oracle 12c中对user_cons_columns的查询要慢得多

时间:2017-06-01 15:35:10

标签: oracle oracle12c

我们正在从Oracle 11g升级到12c,并注意到user_cons_columns上的查询似乎要慢得多。

例如,即使在较小的数据集上,这也是慢4倍:

select uc.search_condition 
from user_constraints uc inner join user_cons_columns ucc on ucc.CONSTRAINT_NAME = uc.CONSTRAINT_NAME  
where ucc.table_name = :upper_table_name
and ucc.column_name = :upper_column

这只是收集统计数据的问题吗?

3 个答案:

答案 0 :(得分:2)

以我的经验,在几个主要的Oracle版本中,从user_constraintsuser_cons_columns中进行选择,其他数据字典视图的速度很慢。不只是12分。进行dbms_stats.gather_dictionary_stats;可以使以下第一个查询的速度提高10-20%。

但真正有用的是使用with提示重写查询以从/*+materialized*/子句“表”中选择,而不是直接从{{1}中选择}表。

此查询在我的设置上非常慢,大约 150秒 :(它返回表列表中的所有外键,包括外键两端的表名和列名)

user_

重写后,查询仅用 1-8秒

select
  cc.table_name, cc.position, cc.constraint_name, cc.column_name,
  cr.table_name r_table_name, ccr.constraint_name r_constraint_name, ccr.column_name r_column_name
from uc     c
join ucc1  cc on cc.constraint_name=c.constraint_name and cc.owner=c.owner and cc.table_name=c.table_name
join ucpu  cr on cr.owner=c.r_owner and cr.constraint_name=c.r_constraint_name and cr.constraint_type in ('P','U')
join ucc2 ccr on ccr.constraint_name=cr.constraint_name and ccr.owner=cr.owner and ccr.table_name=cr.table_name and ccr.position=cc.position
where c.constraint_type='R'
and c.table_name in ('TABLE_A', 'TABLE_B', ........a list of about 157 table names.......)
order by cc.table_name, cc.position, constraint_name, column_name, cc.position;

我还尝试了with uc as (select /*+materialize*/ owner,table_name,constraint_name,constraint_type,r_owner,r_constraint_name from user_constraints), ucc as (select /*+materialize*/ owner,table_name,constraint_name,position,column_name from user_cons_columns) select cc.table_name, cc.position, cc.constraint_name, cc.column_name, cr.table_name r_table_name, ccr.constraint_name r_constraint_name, ccr.column_name r_column_name from uc c join ucc cc on cc.constraint_name=c.constraint_name and cc.owner=c.owner and cc.table_name=c.table_name join uc cr on cr.owner=c.r_owner and cr.constraint_name=c.r_constraint_name and cr.constraint_type in ('P','U') join ucc ccr on ccr.constraint_name=cr.constraint_name and ccr.owner=cr.owner and ccr.table_name=cr.table_name and ccr.position=cc.position where c.constraint_type='R' and c.table_name in ('TABLE_A', 'TABLE_B', ........a list of about 157 table names.......) order by cc.table_name, cc.position, constraint_name, column_name, cc.position; 而不是只在*表中列出所需的列,但这没有帮助。我猜这是因为Oracle是否忽略with提示是否要记住/缓存太多数据。

答案 1 :(得分:1)

<强> 1。收集字典统计信息。

begin
    dbms_stats.gather_dictionary_stats;
end;
/

<强> 2。收集固定对象统计信息。

begin
    dbms_stats.gather_fixed_objects_stats;
end;
/

除非您使用dbms_stats.gather_table_stats专门调用它们,否则还有一些罕见的数据字典对象从未被分析过。

第3。查找损坏的数据字典对象。some rare cases字符集中,问题可能导致数据字典性能问题。在EXPLAIN PLAN上运行SELECT并查找任何内容&#34;奇怪的&#34;,如谓词中的NLSSORT将阻止索引访问。

<强> 4。检查我的Oracle支持。我之前看到过因新版本而降级的数据字典视图的错误。有时,数据字典视图的备用版本可以解决问题。我搜索了My Oracle Support和&#34;数据字典选择在12c中花了很长时间(文档ID 2251730.1)&#34;可能与此相关。我无法在此发布该文章的内容,因此请访问support.oracle.com并查看该错误报告中的解决方法。

<强> 5。认为自己很幸运。如果您只遇到一个性能问题,并且速度只有四倍,我认为升级成功。

答案 2 :(得分:1)

我参加这个聚会有点晚了,但是正如Burleson所建议的那样,在您对Oracle数据字典的查询中使用/ * + RULE * /提示。这有效地关闭了优化器。

Many曾经说过不要使用提示,而RULE提示已经是deprecated,但在我的情况下却有很大的不同。我的一个DBA_IND_COLUMNS查询之一耗时18个 MINUTES ,现在只需不到一秒钟(Oracle 12cR1)。不知所措地说出这是为什么...