
随着数据库的增长,我们可以考虑使用oracle的表压缩技术。表压缩可以节省磁盘空间、减少data buffer cache的内存使用量、并可以显著的提升读取和查询的速度。当使用压缩时,在数据导入和DML操作时,将导致更多的CPU开销,然而,由于启用压缩而减少的I/O需求将抵消CPU的开销而产生的成本。
表的压缩对于应用程序来说是完全透明的,对于决策支持系统(DSS)、联机事务处理系统(OLTP)、归档系统(Archive Systems)来说表的压缩是有益处的。我们可以压缩表空间,表和分区。如果压缩表空间,那么在默认的情况下,表空间上创建的所有表都将被压缩。只有在表执行插入、更新或批量数据载入时,才会执行数据的压缩操作。
估算表的大小 --> 表段 --> 数据库块
select SEGMENT_NAME,BLOCKS from user_segments where SEGMENT_NAME='EMP';
SEGMENT_NAME BLOCKS
--------------- ----------
EMP 8
Table Compression:基本压缩针对直接路径加载的操作
oltp的压缩:针对所有的DML操作
三种选择:
COMPRESS BASIC 针对 direct-path insert (用隐含参数/*+ APPEND */ 在数据块上直接拷贝,不经过数据库的buffer cache) 一般用于数据仓库中大数据的加载
COMPRESS FOR OLTP 针对dml动作
COMPRESS NOCOMPRESS
之前未压缩的表可以通过alter table ... compression ... 语句进行压缩。在这种情况下,压缩启用前的记录不会被压缩,只有新插入或更新的数据才会进行压缩。同样,通过alter table ... nocompression ...语句解除对一个表的压缩,表内已压缩的数据还会继续保持压缩的状态,新插入的数据就不再被压缩。
1. 基本压缩
SQL> create table scott.a5 (id number ,ename varchar(20)) COMPRESS BASIC;
SQL> set long 1000
SQL> select dbms_metadata.get_ddl('TABLE','A5','SCOTT') from dual;
DBMS_METADATA.GET_DDL('TABLE','A5','SCOTT')
----------
CREATE TABLE "SCOTT"."A5"
( "ID" NUMBER,
"ENAME" VARCHAR2(20)
) SEGMENT CREATION DEFERRED
PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 COMPRESS BASIC LOGGING
TABLESPACE "USERS";
插入数据:
insert *+ APPEND */ into scott.a5 select empno ,ename from scott.emp ;
commit;
2. 针对OLTP (不要求直接路径插入)
SQL> create table scott.a6 (id number ,ename varchar(20)) COMPRESS for oltp;
SQLselect dbms_metadata.get_ddl('TABLE','A6','SCOTT') from dual;
DBMS_METADATA.GET_DDL('TABLE','A6','SCOTT')
----------
CREATE TABLE "SCOTT"."A6"
( "ID" NUMBER,
"ENAME" VARCHAR2(20)
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 COMPRESS FOR OLTP LOGGING TABLESPACE "USERS";
SQL> insert into scott.a6 select empno ,ename from scott.emp ;
SQL> commit;
3. COMPRESS NOCOMPRESS 不压缩
SQL> create table scott.a7(id number ,ename varchar(20));
SQL> select dbms_metadata.get_ddl('TABLE','A7','SCOTT') from dual;
DBMS_METADATA.GET_DDL('TABLE','A7','SCOTT')
---------
CREATE TABLE "SCOTT"."A7"
( "ID" NUMBER,
"ENAME" VARCHAR2(20)
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS --不压缩 LOGGING
TABLESPACE "USERS";
启用表压缩:
SQL> alter table emp_comp COMPRESS;
表已更改。
SQL> SELECT table_name, compression, compress_for FROM user_tables WHERE table_name='EMP_COMP';
TABLE_NAME COMPRESS COMPRESS_FOR
-------------- -------- ------------
EMP_COMP ENABLED BASIC
SQL> insert into scott.a7 select empno ,ename from scott.emp;
估算一下a5 a6 a7 的大小
先对表做一统计
SQL> analyze table scott.a5 estimate statistics;
SQL> analyze table scott.a6 estimate statistics;
SQL> analyze table scott.a7 estimate statistics;
select num_rows,blocks,empty_blocks ,avg_space,chain_cnt,avg_row_len from
dba_tables where table_name='A5' and owner='SCOTT';
NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ---------- ------------ ---------- ---------- -----------
140 16 0 7899 0 13
SQL> select num_rows,blocks,empty_blocks ,avg_space,chain_cnt,avg_row_len from
dba_tables where table_name='A6' and owner='SCOTT';
NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ---------- ------------ ---------- ---------- -----------
140 5 3 7659 0 13
SQL> select num_rows,blocks,empty_blocks ,avg_space,chain_cnt,avg_row_len from
dba_tables where table_name='A7' and owner='SCOTT';
NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ---------- ------------ ---------- ---------- -----------
140 5 3 7659 0 13
4. 压缩和分区表
一个表可以有压缩的分区和未压缩的分区,不同的分区可以使用不同的压缩方法。可以采用下列的方法改变分区的压缩方法:
1、alter table ... modify partition ... compress ... ,该方法仅适用于新插入的数据。
2、alter table ... move partition ... compress ... ,该方法适用于新插入的数据和已存在的数据。
确定表是否被压缩:
SQL> select table_name,compression,compress_for from user_tables;
TABLE_NAME COMPRESS COMPRESS_FOR
------------------------------ -------- ------------
COUNTRIES DISABLED BASIC #这里比较困惑,既然表没有启用压缩,为什么compress_for里的压缩方法却是basic呢?
JOBS DISABLED
EMPLOYEES ENABLED BASIC
LOCATIONS DISABLED





