Oracle大表清理truncate .. reuse storage

简介: 最近需要清理一张大表,要求不能影响性能。在MySQL里边我们可以通过借助coreutils以及硬链接的方式来最小化I/O,Oracle也可以通过分批次回收空间来最小化I/O,到底如何,下面我们拭目以待。
最近需要清理一张大表,要求不能影响性能。在MySQL里边我们可以通过借助coreutils以及硬链接的方式来最小化I/O,Oracle也可以通过分批次回收空间来最小化I/O,到底如何,下面我们拭目以待。

一、TRUNCATE TABLE 语法

TRUNCATE TABLE [schema_name.]table_name
  [ PRESERVE MATERIALIZED VIEW LOG | PURGE MATERIALIZED VIEW LOG ]
  [ DROP STORAGE | REUSE STORAGE ] ;
--下面仅列出reuse storage的说明部分  
REUSE STORAGE 
Specify REUSE STORAGE to retain the space from the deleted rows allocated to the table. Storage values are not reset to the values when the table was created. This space can subsequently be used only by new data in the table resulting from insert or update operations. This clause leaves storage parameters at their current settings.

This setting is useful as an alternative to deleting all rows of a very large table—when the number of rows is very large, the table entails many thousands of extents, and when data is to be reinserted in the future. TRUNCATE TABLE with REUSE STORAGE performs several orders of magnitude faster than deleting all rows, but has the following drawbacks:

•You cannot roll back a TRUNCATE TABLE statement.

•All cursors are invalidated.

•You cannot flash back to the state of the table before the truncate operation.

This clause is not valid for temporary tables. A session becomes unbound from the temporary table when the table is truncated, so the storage is automatically dropped.

If you have specified more than one free list for the object you are truncating, then the REUSE STORAGE clause also removes any mapping of free lists to instances and resets the high-water mark to the beginning of the first extent.

二、演示truncate table .. reuse storage(11g)

SQL> select * from v$version where rownum=1;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

SQL> create table tb_reuse as select * from dba_objects;

Table created.

SQL> /     --多次执行

37200896 rows created.

SQL> create table tb_noreuse as select * from tb_reuse;

Table created.

SQL> select count(*) from tb_reuse;

  COUNT(*)
----------
  37200896

SQL>  select count(*) from tb_noreuse;

  COUNT(*)
----------
  37200896

SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_REUSE','TB_NOREUSE');

SEGMENT_NAME                        BYTES/1024/1024
----------------------------------- ---------------
TB_REUSE                                       4165   --占用空间接近4GB
TB_NOREUSE                                     4172

SQL> truncate table tb_noreuse;   --直接truncate,速度很快    

Table truncated.

Elapsed: 00:00:00.25
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_REUSE','TB_NOREUSE');

SEGMENT_NAME                        BYTES/1024/1024
----------------------------------- ---------------
TB_REUSE                                       4165
TB_NOREUSE                                    .0625  -- 空间已回收

Elapsed: 00:00:00.03

SQL> truncate table tb_reuse reuse storage;          --使用reuse storage方式,并无太多性能提升

Table truncated.

Elapsed: 00:00:00.07
SQL> alter table tb_reuse deallocate unused keep 2048;  --这里漏掉了指定m,缺省为byte

Table altered.

Elapsed: 00:00:00.36
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_REUSE','TB_NOREUSE');

SEGMENT_NAME                        BYTES/1024/1024
----------------------------------- ---------------
TB_REUSE                                      .0625
TB_NOREUSE                                    .0625

Elapsed: 00:00:00.03

三、演示truncate table .. reuse storage(12g)

SQL> select * from v$version where rownum=1;

BANNER                                                                               CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production              0

SQL> create table tb_12_use as select * from dba_objects;

Table created.

SQL> insert into tb_12_use select * from tb_12_use;

90903 rows created.

SQL> /

11635584 rows created.

SQL> create table tb_12_nouse as select * from tb_12_use;

Table created.

SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_12_USE','TB_12_NOUSE');

SEGMENT_NAME                   BYTES/1024/1024
------------------------------ ---------------
TB_12_NOUSE                               3074   --使用空间为3GB
TB_12_USE                                 3072

SQL> select 'Leshami' As author,'http://blog.csdn.net/leshami' as Blog from dual;

AUTHOR  BLOG
------- ----------------------------
Leshami http://blog.csdn.net/leshami

SQL> set timing on;
SQL> truncate table TB_12_NOUSE;              --使用常规方式truncate

Table truncated.

Elapsed: 00:00:01.73
SQL> truncate table TB_12_USE reuse storage;  --使用reuse storage方式,并无太多性能提升

Table truncated.

Elapsed: 00:00:01.10
SQL> alter table TB_12_USE deallocate unused keep 2048m; 

Table altered.

Elapsed: 00:00:00.25
SQL> alter table TB_12_USE deallocate unused keep 1m;

Table altered.

Elapsed: 00:00:00.14
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_12_USE','TB_12_NOUSE');

SEGMENT_NAME                   BYTES/1024/1024
------------------------------ ---------------
TB_12_NOUSE                              .0625
TB_12_USE                               1.0625

Elapsed: 00:00:00.03

-- 由于前面的测试在非归档模式,因此重启切换到归档模式后再次测试
SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     396
Next log sequence to archive   398
Current log sequence           398

SQL> select count(*) from tb_12_use;

  COUNT(*)
----------
  23273472

SQL> select count(*) from tb_12_nouse;

  COUNT(*)
----------
  23273472

SQL> truncate table TB_12_NOUSE;    

Table truncated.

Elapsed: 00:00:02.07

SQL> truncate table TB_12_USE reuse storage; --归档后使用reuse storage方式,同样无太多性能提升
                                             --因为truncat属于DDL,本身并不会产生太大arch
Table truncated.

Elapsed: 00:00:00.76

四、小结

a、通过上述测试,当使用reuse storage与普通方式并无明显差异
b、truncate table 是ddl操作,无法回滚
c、尽管无明显性能差异,生产环境大表情况,还是建议使用reuse storage结合deallocate方式

目录
相关文章
|
5月前
|
SQL Oracle 关系型数据库
"揭秘!一键解锁Oracle日志清理魔法,让海量归档日志无处遁形,守护数据库健康,告别磁盘空间告急噩梦!"
【8月更文挑战第9天】随着Oracle数据库在企业应用中的普及,归档日志管理对保持数据库健康至关重要。归档日志记录所有更改,对数据恢复极为重要,但也可能迅速占用大量磁盘空间影响性能。利用Oracle提供的RMAN工具,可通过编写Shell脚本来自动清理归档日志。脚本包括设置环境变量、连接数据库、检查和删除指定时间前的日志,并记录执行情况。通过Cron作业定时运行脚本,可有效管理日志文件,确保数据库稳定运行。
133 7
|
8月前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—Oracle数据库误truncate table的数据恢复案例
北京某国企客户Oracle 11g R2数据库误truncate table CM_CHECK_ITEM_HIS,表数据丢失,业务查询到该表时报错,数据库的备份不可用,无法查询表数据。 Oracle数据库执行Truncate命令的原理:在执行Truncate命令后ORACLE会在数据字典和Segment Header中更新表的Data Object ID,但不会修改实际数据部分的块。由于数据字典与段头的DATA_OBJECT_ID与后续的数据块中的并不一致,所以ORACLE服务进程在读取全表数据时不会读取到已经被TRUNCATE的记录,但是实际数据未被覆盖。
Oracle数据恢复—Oracle数据库误truncate table的数据恢复案例
|
8月前
|
SQL Oracle 关系型数据库
Oracle-使用切片删除的方式清理非分区表中的超巨数据
Oracle-使用切片删除的方式清理非分区表中的超巨数据
124 1
|
Oracle 关系型数据库
Oracle自带adrci工具清理告警日志
Oracle自带adrci工具清理告警日志
670 0
Oracle自带adrci工具清理告警日志
|
Oracle 关系型数据库
Oracle trace文件的清理
Oracle trace文件的清理
605 0
Oracle trace文件的清理
|
Oracle 关系型数据库
Oracle查询前几张大表
Oracle查询前几张大表
249 1
|
监控 关系型数据库 测试技术
你敢在Oracle 12c R2上做大表truncate吗?
笔者所处的省份正在做生产全网段的Oracle 12c升级,在正式割接前搭建了准生产环境用于应用测试,前期应用功能测试均正常,在进行二次模割对历史数据进行清理的时候,数据库发生了hang以及节点重启的问题。
2122 0