Oracle 12 - 提高插入性能

Oracle 12 - Improve Insert performance

我们正在迁移一个拥有庞大数据集的遗留项目(100 多个表,其中许多是 1000 万条以上的记录)。其中很少有很大的(大约 1 亿)。

当我们切换应用程序时,我们将只有几个小时的时间将此数据迁移到具有相同 table 但结构略有不同(因此无法导入或抽取)的新应用程序。

我们正在插入如下记录:

  1. 创建了一个从源数据库到目标数据库的数据库Link
  2. 禁用目标 table(和子 table 上的所有约束,如果有的话)
  3. 将所有索引更改为不可用
  4. INSERT /+ APPEND NOLOGGING PARALLEL/ INTO destination_table SELECT /*+ PARALLEL */ FROM source_table
  5. REBUILD 所有索引(REBUILD PARALLEL NOLOGGING 然后更改为 NOPARALLEL 和 LOGGING)
  6. 在目的地 table(和子 table 上启用所有约束,如果有的话)

它运行良好但需要更长的时间才能完成(大约 1000 万条记录平均需要 5 分钟)。大部分时间花在步骤 6 上,特别是用于 FOREIGN KEY 约束,其中 Parent 和 Child 都很大。

如上所述,我们如何优化数据库的插入性能?

好吧,如果您正在寻找性能,那么通过 db_link 传输数据会遇到问题。

将数据卸载到平面文件,然后设置外部 table/CTAS 或 SQL 加载器将数据加载到新系统中。它将 显着 更快。

A very small example showing the type of rates I was able to achieve on just a laptop and a VM.

TL/DR;

每秒 112,000 行通过 SQL 加载程序...在 windows 笔记本电脑上。

如果您只有两个小时的时间来迁移一个巨大的项目,您可以执行以下操作:

  1. 在第 4 步后将数据设置为只读(可能为项目使用单独的表空间,然后执行 alter tablespace new_stuff read only;
  2. 让用户进入应用程序。用户可以查看数据(可能会很慢,直到完成第 5 步)
  3. 完成第 6 步后,将表空间更改为 read write

很高兴收到不同的方法,但是我们将改进我们的方法(因为我们已经有了可行的解决方案)。据说这肯定不是“最佳”方式,但它解决了我们在这种特定情况下的担忧。

所以我们最终遵循的步骤是;

  1. 禁用对目标的所有约束Table(以及子表,如果有的话)
  2. 禁用目标上的所有索引Table
  3. 增加序列缓存(如果使用)
  4. 执行 INSERT(提示 APPEND 和 NOLOGGING)INTO SELECT(提示 PARALLEL)
  5. 使用 PARALLEL NOLOGGING
  6. 在目标 Table 上重建所有索引
  7. 更改索引以更改为 NOPARALLEL & LOGGING
  8. 使用 NOVALIDATE(和子表,如果有的话)启用所有约束
  9. 改变 TABLE TABLE_NAME 平行
  10. 使用 VALIDATE
  11. 启用所有约束
  12. ALTER TABLE TABLE_NAME NOPARALLEL

对以

开头的脚本中的所有表重复上述步骤

改变会话启用并行 DDL

Tables: 99

Records: 593,960,688

Time taken: 01:23:44 Hrs