【问题标题】:drop/truncate and rollback segment删除/截断和回滚段
【发布时间】:2011-02-11 17:06:31
【问题描述】:

我知道 drop 会删除数据以及表结构,而 truncate 会保留表结构。

是否删除/截断写入回滚段?

【问题讨论】:

  • 您的问题被标记为oraclemysql。如果您希望对他们两个都回答您的问题,我认为您应该在问题中说明这一点。

标签: database oracle truncate sql-drop rollbacksegments


【解决方案1】:

在 Oracle 中,答案是否定的,因为回滚段仅用于 DML。

TRUNCATE 是 DDL。

【讨论】:

  • 好的。还有1个问题。我知道删除是DML,截断是DDL。给定名为employees的表,1.delete from employees有什么区别; 2.截断员工;什么时候使用每个?
  • 截断要快得多,部分原因是它不会产生回滚。这导致了至少两个重要的区别:显然,它不能回滚,并且独立于提交而立即生效。假设您要清空并重新填充表格。如果您删除、插入、提交,那么就其他用户而言,该表永远不会为空,并且如果您回滚旧数据,则会恢复。如果您截断、插入、提交,那么所有其他会话会在截断和提交之间看到一个空表,这可能会导致问题,如果插入失败并回滚,则它保持为空。
  • 为了完美,把2更正为2.truncate table employees
【解决方案2】:

每个单独的 DDL 语句都是一个离散事务。这是因为数据库需要管理它们的元数据(Oracle 中的数据字典)。基本上它必须始终正确且有效,因此对元数据的更改无法回滚。因此,在每个 DDL 语句之前和之后都会发出隐式 commit。这适用于大多数(可能是所有)RDBMS 产品。

TRUNCATE TABLE 和 DROP TABLE 都是 DDL 语句都是 DDL,所以没有回滚。如果我们拥有最新版本 Oracle 的企业版许可证,我们可以使用 FLASHBACK TABLE 将表恢复到以前的状态,包括 BEFORE DROP。

编辑

以下是 DELETE 和 TRUNCATE TABLE 之间的区别。示例日期是这个大表:

SQL> exec dbms_stats.gather_table_stats(user,'BIG_TABLE')

PL/SQL procedure successfully completed.

SQL> select blocks, num_rows
  2  from user_tables
  3  where table_name = 'BIG_TABLE'
  4  /

    BLOCKS   NUM_ROWS
---------- ----------
     15449    2340320

SQL> 

先删除....

SQL> delete from big_table
  2  /

2340320 rows deleted.

Elapsed: 00:01:20.37
SQL>
SQL> exec dbms_stats.gather_table_stats(user,'BIG_TABLE')

PL/SQL procedure successfully completed.

Elapsed: 00:00:10.20
SQL>
SQL> select blocks, num_rows
  2  from user_tables
  3  where table_name = 'BIG_TABLE'
  4  /

    BLOCKS   NUM_ROWS
---------- ----------
     15449          0

Elapsed: 00:00:00.11
SQL>

现在截断...

SQL> truncate table big_table reuse storage
  2  /

Table truncated.

Elapsed: 00:00:08.31
SQL> exec dbms_stats.gather_table_stats(user,'BIG_TABLE')

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.26
SQL>
SQL> select blocks, num_rows
  2  from user_tables
  3  where table_name = 'BIG_TABLE'
  4  /

    BLOCKS   NUM_ROWS
---------- ----------
         0          0

Elapsed: 00:00:00.00
SQL>

两者之间的差异是显而易见的。 TRUNCATE 快得多。它也将表中的块数归零。请注意,即使在截断后收集统计信息也会更快。这是因为 TRUNCATE 语句重置了高水位线(即零块),因此作业知道所有分配的块都未使用。

【讨论】:

    【解决方案3】:

    删除和截断写入回滚段。
    您不能自己进行回滚,因为 Oracle 在自动启动和提交的单独事务中执行每个 DDL 语句。

    它是这样工作的:

    begin
        COMMIT; -- any outstanding work
        begin
           DDL statement;
           COMMIT; -- the DDL statement
        exception
           when others then
                ROLLBACK;  -- any work done by the DDL
                RAISE;     -- reraise the exception back to the client
        end;
    end;
    

    如果在 DDL 语句中间发生系统崩溃,Oracle 将能够回滚中断的操作。

    信息来源:article on Ask Tom

    【讨论】:

      【解决方案4】:

      【讨论】:

      • 我建议详细说明该网站为何有用。
      猜你喜欢
      • 2020-04-11
      • 1970-01-01
      • 2010-12-18
      • 2014-05-25
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      • 2015-06-03
      相关资源
      最近更新 更多