1

我们在 prod 环境中使用 Goldengate 进行了复制。这些表最初是从 prod 中转储的,然后我们使用 Goldengate 开始复制。现在我们要将数据迁移到另一个数据库。但是查询计划与 prod 环境不同。我们认为这是因为复制数据库中的所有统计信息都被破坏/错误。dba_tables 中规定的行数为空、0 或相差 50-80%。我们试图dbms_stats.gather_table_stats在所有相关表上做。它还是坏了。我们对所有统计信息错误的表运行该查询:

dbms_stats.GATHER_TABLE_STATS(OWNNAME => 'SCHEMA', TABNAME => 'TABLE_NAME', CASCADE => true);

我们无法使用错误的查询计划进行迁移。

我们正在使用 Oracle 版本 12.2.0.1.0 - 生产

编辑:在@Jon Heller 的回答之后,我们看到一些索引在 prod 环境中而不是在复制中进行了分区。此外,全局首选项 DEGREE 在复制上为 32768,在生产上为 NULL。

4

1 回答 1

1

这些表的构建方式是否完全相同?可能是不同的表结构导致统计信息中断,例如一个表已分区而另一个表未分区。尝试比较 DDL:

select dbms_metadata.get_ddl('TABLE', 'TABLE1') from dual;

即使在收集了统计数据之后,我也很惊讶地听到统计数据是错误的。尤其是行数——从 10g 开始,这个数字在默认设置下应该总是 100% 准确。

你能列出你用来收集统计数据的确切命令吗?此外,这是一个延伸,但可能在一个数据库上更改了全局偏好。这将是非常邪恶的,但是您可以将数据库默认设置为仅查看 0.00001% 的数据,这将产生可怕的统计数据。检查两个数据库之间的全局首选项。

--Thanks to Tim Hall for this query: https://oracle-base.com/dba/script?category=monitoring&file=statistics_prefs.sql
SELECT DBMS_STATS.GET_PREFS('AUTOSTATS_TARGET') AS autostats_target,
       DBMS_STATS.GET_PREFS('CASCADE') AS cascade,
       DBMS_STATS.GET_PREFS('DEGREE') AS degree,
       DBMS_STATS.GET_PREFS('ESTIMATE_PERCENT') AS estimate_percent,
       DBMS_STATS.GET_PREFS('METHOD_OPT') AS method_opt,
       DBMS_STATS.GET_PREFS('NO_INVALIDATE') AS no_invalidate,
       DBMS_STATS.GET_PREFS('GRANULARITY') AS granularity,
       DBMS_STATS.GET_PREFS('PUBLISH') AS publish,
       DBMS_STATS.GET_PREFS('INCREMENTAL') AS incremental,
       DBMS_STATS.GET_PREFS('STALE_PERCENT') AS stale_percent
FROM   dual;

如果收集统计数据仍然导致不同的结果,我唯一能想到的就是腐败。可能是时候创建一个 Oracle 服务请求了。

(这更像是一个扩展评论而不是一个答案,但可能需要大量代码来诊断这个问题。请在找到时使用更多信息更新原始问题。)

于 2019-10-10T02:39:37.970 回答