我有一个包含1亿行的子表,需要使用父表中的值更新5000万行。我已经读过,假设我们有足够的空间,那么创建表作为选择"是最快的,但我想知道是否有人不同意或者是否需要其他因素才能做得更好猜测?与使用pl / sql的BULK COLLECT FORALL UPDATE功能相比,走这条路会更好吗?
答案 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。但重新创建对象通常是错误的,并且获得最佳性能是棘手的。
在决定简单地删除并重新创建表之前,需要考虑以下事项:
DBMS_METADATA
可能很棘手,在某些情况下仍然无法使对象完全同样的方式。如果您决定对DDL进行硬编码,则必须记住在对象发生更改时更新进程。ORA-04068: existing state of packages has been discarded
错误。 (因为大多数PL / SQL程序员不知道会话状态,并且默认情况下将每个包变量公开。)NOLOGGING
,然后记住最后将它们设置回LOGGING
。重新创建外键时,如果要并行执行,则必须首先将其创建为NOVALIDATE
,将表设置为并行,启用验证约束,然后将表设置回{{ 1}}。在大型数据仓库中,值得完成所有这些步骤并构建处理所有问题的代码。如果这是您唯一的大表NOPARALLEL
,我建议您避免这项工作,并接受稍微不理想的解决方案。