Oracle BEST PRACTICE使用父表

时间:2017-07-12 21:23:10

标签: sql oracle plsql bulkupdate

我有一个包含1亿行的子表,需要使用父表中的值更新5000万行。我已经读过,假设我们有足够的空间,那么创建表作为选择"是最快的,但我想知道是否有人不同意或者是否需要其他因素才能做得更好猜测?与使用pl / sql的BULK COLLECT FORALL UPDATE功能相比,走这条路会更好吗?

2 个答案:

答案 0 :(得分:1)

如果你有大量数据,那么CREATE TABLE AS SELECT肯定更快,因为它不需要UNDO表空间。但是,由于名称冲突,重新创建新表上的所有索引可能会非常麻烦。

好消息是:50分钟的行并不是真正的大量数据。如果你有一个现代化的中端服务器,它不应该导致问题,因此不值得额外的工作。找出的最好方法是制作原始表的副本(包括所有索引)并在那里尝试更新。然后你会大致了解需要多长时间。

答案 1 :(得分:0)

并行UPDATE可能是对子表进行大量更改的最佳选择。 (如果您有Enterprise Edition,足够的资源,合理的配置等)。

alter session enable parallel dml;
update /*+ parallel */ ...;

(您可能希望使用不同的并行数字,例如parallel(8)。默认的并行度通常足够好。但是像SPARC这样的平台会夸大他们的" CPU_COUNT",导致荒谬并行度。)

并行更新可能不是最佳解决方案。重新创建对象可以更快,因为它几乎可以完全避免生成REDO和UNDO。但重新创建对象通常是错误的,并且获得最佳性能是棘手的。

在决定简单地删除并重新创建表之前,需要考虑以下事项:

  1. Grants。在重新创建对象后保存并重新应用对象授权。
  2. 依赖对象。该进程需要以完全相同的方式重新创建所有对象和依赖对象。根据架构的复杂程度,这可能会非常困难。 DBMS_METADATA可能很棘手,在某些情况下仍然无法使对象完全同样的方式。如果您决定对DDL进行硬编码,则必须记住在对象发生更改时更新进程。
  3. 无效对象。大多数对象会在必要时自动重新编译。但是你可能不想等待它,因为拥有无效对象总是看起来很糟糕。即使它们编译正确,某些程序仍可能会出现那些令人讨厌的ORA-04068: existing state of packages has been discarded错误。 (因为大多数PL / SQL程序员不知道会话状态,并且默认情况下将每个包变量公开。)
  4. 统计信息。在重新创建表格后重新收集它们并不总是足够的。直方图取决于列是否用于谓词。如果重新创建表,则所有列都是新的,并且最初不会创建直方图。
  5. 直接路径写入难以捉摸。父子表意味着外键,通常会阻止直接路径写入。该过程需要禁用或删除外键。并将表和索引设置为NOLOGGING,然后记住最后将它们设置回LOGGING。重新创建外键时,如果要并行执行,则必须首先将其创建为NOVALIDATE,将表设置为并行,启用验证约束,然后将表设置回{{ 1}}。
  6. 在大型数据仓库中,值得完成所有这些步骤并构建处理所有问题的代码。如果这是您唯一的大表NOPARALLEL,我建议您避免这项工作,并接受稍微不理想的解决方案。