我们正在从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
这只是收集统计数据的问题吗?
答案 0 :(得分:2)
以我的经验,在几个主要的Oracle版本中,从user_constraints
和user_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)。不知所措地说出这是为什么...