drop / truncate和rollback segment

时间:2010-04-23 20:45:54

标签: database oracle truncate sql-drop rollbacksegments

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

drop / truncate是否写入回滚段?

3 个答案:

答案 0 :(得分:2)

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

TRUNCATE TABLE和DROP TABLE都是DDL语句,因此没有回滚。如果我们拥有最新版Oracle的Enterprise Edition许可证,我们可以使用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语句重置高水位线(即零块),因此作业知道所有分配的块都未使用。

答案 1 :(得分:1)

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

TRUNCATE是DDL。

答案 2 :(得分:0)

drop和truncate都写入回滚段 您无法自行回滚,因为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