我知道 drop 会删除数据和表格结构,而 truncate 会保留表格结构。
drop / truncate是否写入回滚段?
答案 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。