专栏首页乐沙弥的世界Oracle大表清理truncate .. reuse storage

Oracle大表清理truncate .. reuse storage

最近需要清理一张大表,要求不能影响性能。在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方式

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 当心外部连接中的ON子句

           在SQL tuning中,不良写法导致SQL执行效率比比皆是。最近的SQL tuning中一个外部连接写法不当导致过SQL执行时间超过15分钟左右...

    Leshami
  • 参数job_queue_processes与Oracle jobs

    Oracle jobs为Oracle开发人员和数据库管理员提供了数据库层面维护的极大便利性。对于Oracle jobs在Oracle 9i之前,是由dbms_...

    Leshami
  • consistent gets减少,cost增加?

      在一条SQL语句中,当使用索引时,cosistent gets 减少,而cost增加。理论上在稳定后的执行计划中,physical reads为零值的前...

    Leshami
  • centos7下NFS使用与配置的步骤

    NFS是Network File System的缩写,即网络文件系统。客户端通过挂载的方式将NFS服务器端共享的数据目录挂载到本地目录下。

    砸漏
  • ZABBIX 自定义采集触发时间范围

    周一到周五每天上午09:15-11:30 每隔5秒获取一次数据,下午13:00-15:00每隔10秒获得一次数据,其它时间段不获取数据。

    Kevin song
  • Scrapy之图片爬取。

    首先假设我们要自己写一个获取图片的爬虫吧。那么显然,你需要的就是获取图片链接,然后写一个专门下载图片的pipline。很开心的是,scrapy其实已经给你实现好...

    钱塘小甲子
  • Kubernetes 1.19.0——服务svc(2)

    在kube-system里有dns,可以自动发现所有命名空间里的服务的clusterIP

    gz_naldo
  • 2019年腾讯云服务器爆品抢购进行中1核1G1年仅168元

    活动时间:2018年12月12日至2019年1月25日,每天两场秒杀,时间分别为:9:00-12:00,14:00-18:00。

    聚优云惠
  • Python生成CSV文件模拟某小区用户手机通话记录

    编写Python程序,生成CSV文件模拟某小区1000位用户2020年7月1日0时至2020年11月1日0时每次通话的开始时间和时长。数据格式如下:

    Python小屋屋主
  • 使用goaccess分析nginx日志

    GoAccess 是一款开源(MIT许可证)的且具有交互视图界面的实时 Web 日志分析工具,通过你的 Web 浏览器或者 *nix 系统下的终端程序即可访问。

    三杯水Plus

扫码关注云+社区

领取腾讯云代金券