Alter table move compress是如何工作的?

本文详细阐述了在Oracle数据库中使用ALTER TABLE MOVE COMPRESS技术的本质及其应用,通过创建表空间、创建表、数据迁移与压缩的过程,展示了如何在不减少可用空间的前提下优化存储效率。同时,文章还通过查询数据字典,直观地展示了表空间高水位线的变化,以及数据压缩前后空间利用率的提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

alter table move compress的技术本质是通过在新的表空间或当前表空间中分配新的extents来存放压缩后的数据而实现的。而原来分配给该表的这些extents只释放供重用但不会被收缩(shrik high-water-mark).从这个角度来说,如果我们需要对一个大表做alter table move compress的动作的话,那么你就必须要确保目标表空间上存在额外的空间,从而保证这个动作的顺利执行.

下面通过看一个简单的测试就能明白这个基本原理了

测试环境:10.2.0.4,db_block_size=8K 表

首先,创建一个LMT+Uniform(1M)+MSSM的表空间,我这里叫LMT_UNIFORM_MSSM.

SQL> select a.tablespace_name,
2 a.file_name,
3 (b.maximum+c.blocks-1)*8192 highwater
4 from dba_data_files a,
5 (select file_id,max(block_id) maximum from dba_extents group by file_id) b,
6 dba_extents c
7 where a.file_id = b.file_id and
8 c.file_id = b.file_id and
9 c.block_id = b.maximum and
10 a.tablespace_name='LMT_UNIFORM_MSSM'
11 /

TABLESPACE_NAME FILE_NAME HIGHWATER
------------------ --------------- ----------

SQL>


可以看到这个时候,表空间LMT_UNIFORM_MSSM还是空的,没有任何对象。

创建一张普通表,放在表空间LMT_UNIFORM_MSSM,再看看LMT_UNIFORM_MSSM对应的datafile的highwater

SQL> create table zrp tablespace LMT_UNIFORM_MSSM as select * from dba_objects;
Table created

SQL> select segment_name,bytes from user_segments where segment_name='ZRP';
SEGMENT_NAME BYTES
---------------- -------
ZRP 6291456 
<-6M
SQL>

SQL> select a.tablespace_name,
2 a.file_name,
3 (b.maximum+c.blocks-1)*8192 highwater
4 from dba_data_files a,
5 (select file_id,max(block_id) maximum from dba_extents group by file_id) b,
6 dba_extents c
7 where a.file_id = b.file_id and
8 c.file_id = b.file_id and
9 c.block_id = b.maximum and
10 a.tablespace_name='LMT_UNIFORM_MSSM'
11 /

TABLESPACE_NAME FILE_NAME HIGHWATER
------------------ ------------------------------------------------ ---------
LMT_UNIFORM_MSSM D:ORACLE10GORADATAORA10GLMT_UNIFORM_MSSM.DBF 6356992

SQL> select 6356992-6291456 from dual;
6356992-6291456
---------------
65536 
<--LMT段头(64k)
SQL>

这个时候该对象占用了6M多(Uniform size=1M)的空间,对应的datafile的highwater也扩展到了6356992(6M+64K)

节下来对这张表ZRP进行move compress(在同一表空间内)

SQL> alter table zrp move compress;
Table altered
SQL>

SQL> select segment_name,bytes from user_segments where segment_name='ZRP';
SEGMENT_NAME BYTES
-------------- -------
ZRP 2097152
SQL>

可以看到,数据从原来的6个extents(6M)压缩到了2个extents(2M)。

看一下datafile的highwater是不是也降下来了?

SQL> select a.tablespace_name,
2 a.file_name,
3 (b.maximum+c.blocks-1)*8192 highwater
4 from dba_data_files a,
5 (select file_id,max(block_id) maximum from dba_extents group by file_id) b,
6 dba_extents c
7 where a.file_id = b.file_id and
8 c.file_id = b.file_id and
9 c.block_id = b.maximum and
10 a.tablespace_name='LMT_UNIFORM_MSSM'
11 /

TABLESPACE_NAME FILE_NAME HIGHWATER
------------------ ------------------------------------------------ ---------
LMT_UNIFORM_MSSM D:ORACLE10GORADATAORA10GLMT_UNIFORM_MSSM.DBF 8454144

SQL> select 8454144-6356992 from dual;
8454144-6356992
---------------
2097152
SQL>

正好是又在原来的datafile上又扩展了2个extents(2M).datafile上的highwater并没有降下来.

从下面的数据字典也可以看到,原来的那6个extent确实是空闲可以重新使用了.

SQL> select tablespace_name,file_id,block_id,bytes,blocks from dba_free_space where tablespace_name = 'LMT_UNIFORM_MSSM';
TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS
------------------- ---------- ---------- ---------- -------
LMT_UNIFORM_MSSM 9 9 6291456 768
LMT_UNIFORM_MSSM 9 1033 1048576 128
SQL>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值