Oracle truncate 和 insert(备份表数据太花时间了

问题描述 投票:0回答:1

我们有大表(很多列)Table1,但只有少量列需要备份并进行进一步处理 这是计划。我们创建另一个 Table2,只包含几列(基本数据)

当我们需要备份整个表并做一些清理工作时

  1. 截断表表2(59秒)
  2. INSERT /+ PARALLEL/ INTO table2 SELECT col1, col2, col3 FROM tabl1 (229 秒)
  3. 截断表表1(182秒)

table1大约有50M行。但按照上面的步骤运行,花费了太多时间。 我不明白为什么 TRUNCATE 表花了这么长时间(我认为可能只有几秒钟,对吧?)。谁能解释一下吗? 我们这样设计的原因是,我们有一些操作需要用特定数据更新整个table1的某些列,但是这个过程花费了太多时间。所以我们设计了像上面这样的方式。

我们不能删除 table1 并需要它始终在线(table1 可以被许多会话访问),但我们可以截断它的数据(因为我们相信截断 Table1 应该比 UPDATE table1 快得多)。我们有一个空闲进程,它将在安静的时间处理 Table2 中的数据,并在系统不忙时将其插入回 Table1。 Table2 仅由一个会话访问,因此它没有锁。但是我们不知道为什么 truncate table2 甚至需要这么长时间(table2 应该没有数据或数据量很少),但看起来 ORacle truncate table1 和 table2 花了这么长时间

oracle-database
1个回答
0
投票

虽然

truncate
不需要重新格式化数据块,因此被认为是“快速”,但它确实需要 (1) 获得表上的独占锁 (2) 强制检查点并 (3) 释放其所有范围文件头。

因此,#1 确保当您尝试截断时表中没有发生 DML 活动,#2 确保 DBWR 在此期间不会受到影响(与您的 DBA 交谈),#3 确保没有过多的数量范围。

SELECT extents FROM user_segments WHERE segment_name = 'TABLE1'

如果表已分区,请设为

SUM(extents)
。现在,如果它报告数千个范围(> 10,000),那么这就是您的问题。理想情况下,我们需要数十个或数百个。一旦数量达到数千,就会开始产生负面影响。与您的 DBA 讨论如何定义表空间的分配(统一范围与自动分配/系统),并将表移动到分配较少范围的表空间。

对于插入,

INSERT /+ PARALLEL/ INTO table2
不是有效的提示。确保您没有遗漏提示中的
*
分隔符,添加
ENABLE_PARALLEL_DML
提示(如果没有它,您的实际加载操作将不会并行化,除非您在会话中显式启用了并行 DML),并且还提供了
PARALLEL
提示的实际DOP(并行度) - 不要像这样单独使用
PARALLEL
提示,否则可能会过度分配PX 从机:

 INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(16) */ INTO table2 SELECT ...
© www.soinside.com 2019 - 2024. All rights reserved.