oracle 10g 和 9i 之间巨大的查询执行时间差异

Posted

技术标签:

【中文标题】oracle 10g 和 9i 之间巨大的查询执行时间差异【英文标题】:HUGE query execution time difference between oracle 10g and 9i 【发布时间】:2010-05-06 10:36:34 【问题描述】:

我正在运行以下查询:

SELECT * FROM all_tab_cols c
LEFT JOIN all_varrays v ON c.owner = v.owner
    AND c.table_name = v.parent_table_name
    AND c.column_name = v.parent_table_column

在 10g 服务器上这需要大约 2 秒,在 9i 上这需要 819 秒(13 分钟)!究竟是什么导致了这种巨大的性能差异,我该如何解决?

【问题讨论】:

为什么重要?为什么不直接使用 Oracle 10/11g? 因为我正在开发的应用需要连接11g、10g和9i。 第一个问题:你比较的两个数据库中 all_tab_cols 和 all_varrays 的行数是否相同? 同一个数量级。 9i: 35046, 301. 10g: 50317, 383. 所以 9i 服务器应该做的工作少得多。 能看一下查询计划吗? 【参考方案1】:

事实证明,默认情况下,9i 没有关于系统表的统计信息,而 10g+ 有。这就是导致性能差异的原因 - Oracle 不知道它应该如何正确加入它。

【讨论】:

【参考方案2】:

差异的一个潜在解释是数据字典统计信息。在 10g 中,Oracle 引入了DBMS_STATS.GATHER_DICTIONARY_STATS() procedure,它针对 SYS 和 SYSTEM 模式(以及其他一些模式)收集统计信息。对数据字典进行统计可以改进针对数据库视图的某些查询的执行计划。

即使您运行 DBMS_STATS.GATHER_DATABASE_STATS(),它仍然会收集数据字典的统计信息,除非您将 gather_sys 参数显式设置为 false

您可以使用以下查询检查针对 10g 数据库运行的统计信息收集操作:

SQL> select * from  DBA_OPTSTAT_OPERATIONS
  2  order by start_time asc
  3  /

OPERATION                                                        TARGET
---------------------------------------------------------------- ----------------
START_TIME
---------------------------------------------------------------------------
END_TIME
---------------------------------------------------------------------------
gather_database_stats(auto)
10-APR-10 06.00.03.953000 +01:00
10-APR-10 06.18.21.281000 +01:00

<snip/>

gather_database_stats(auto)
03-MAY-10 22.00.05.734000 +01:00
03-MAY-10 22.03.08.328000 +01:00

gather_dictionary_stats
06-MAY-10 13.48.49.839000 +01:00
06-MAY-10 13.57.42.252000 +01:00


10 rows selected.

SQL>

【讨论】:

以上是关于oracle 10g 和 9i 之间巨大的查询执行时间差异的主要内容,如果未能解决你的问题,请参考以下文章

从 Oracle 9i 到 Oracle 10g 的归档日志传输

从Oracle9i RMAN全库备份迁移到 Oracle10g

expdp在oracle 9.0里能用吗

Oracle 9i & 10g编程艺术-深入数据库体系结构-学习笔记(持续更新中)

Oracle10g新特性——正则表达式 - 转

Oracle Flashback Technologies (总)