我想运行一个涉及80,000,000条记录的PL/SQL过程。
此PL/SQL过程删除大约80,000,000条记录,并将它们备份到使用ON COMMIT PRESERVE ROWS子句创建的全局临时表中。
如何知道在COMMIT PRESERVE ROWS上有多少记录可以包含这个全局临时表?
如果只在PL/SQL过程结束时提交,这些表的大小限制是多少?
发布于 2010-09-03 17:39:47
有两个因素会限制您可以插入的行数:临时空间和撤消空间。
临时表空间中有多少空间,就可以在临时表中放入多少数据。如果允许临时表空间增长(使用自动扩展的数据文件和表空间),则只会受到磁盘空间的限制。现在,您希望估计行的大小,并为开销留出一些额外的空间。这将使您大致估计出临时表空间所需的大小。
单个事务需要完全适合还原表空间。insert的撤销数据比其他DML要小,仍然有80M的行会产生大量的撤销。如果您还从其他表中删除这些行,则撤消操作将占用与原始行大致相同的空间。您可能正在使用自动撤消管理,只需将表空间及其数据文件设置为自动扩展即可。
如果这是一次性操作,您可能希望在完成后减小临时表空间和还原表空间的大小。如果您要定期执行此操作,只需让表空间增长,然后将它们保留在那里即可。
80M行事务的唯一真正问题是,如果出现问题,您可能会遇到非常长的回滚时间。特别是删除的行会使您的回滚比实际删除的时间长得多。
虽然Oracle和大型事务没有什么根本问题(Oracle将进行扩展),但将总工作划分为较小的工作单元将允许您更快地重新启动进程,并在出现故障的情况下对较小的数据子集进行重新启动。
发布于 2010-09-03 18:15:18
如果唯一的commit是在过程的末尾,那么on commit子句就有点无关紧要了,除非这个过程只是一个更大进程的一部分。当您的会话结束时,无论on commit设置如何,GTT数据都将消失,因此您的“备份”数据仅在执行该过程的会话中可用。从给定的上下文来看,不清楚你是否意识到你的“备份”是暂时的。
on commit preserve rows子句的作用是允许您在会话期间提交非GTT数据,而不会丢失GTT中的内容。假设你想要删除数据块,一次可能有一百万行。因此,您确定了您的百万行,将它们复制到GTT,从原始表中删除它们,然后提交。如果您的on commit设置为delete rows,那么此时您的GTT再次为空,因此您没有备份。但是,如果您的on commit是preserve rows,那么您的GTT将保留您插入的百万行。
重复80次...最后,使用delete rows时,GTT是空的,并且一次保存的行数永远不会超过一百万行;使用preserve rows时,它每次都会增长,并且将包含全部8000万条记录。但仍然只是在会话结束之前。
使用preserve rows,如果您在任何时候遇到问题,您可以将“备份”中的所有数据重新插入到原始表中。使用delete rows,您只能重新插入自上次提交以来已删除的所有内容-但随后您也可以在该点上回滚。
https://stackoverflow.com/questions/3634113
复制相似问题