Table Compression in Oracle

Oracle enterprise edition allows you to compress tables or specific partitions to save disk space. This feature was introduced in Oracle 9i version.

Note: Do not use this option unnecessarily. You must read the considerations at the end of this article

Create compressed table

You must add COMPRESS clause while creating a table. By default, every table is created with NOCOMPRESS option

CREATE TABLE COMP_TEST(
  id number(4), 
  std_name varchar2(20)
)
COMPRESS;

Check compression status

You can query DBA_TABLES to check compression status of a table

SELECT TABLE_NAME, COMPRESSION FROM DBA_TABLES
WHERE TABLE_NAME LIKE 'COMP_TEST';

Change compression status

You can always change compression status of an existing table.

ALTER TABLE COMP_TEST NOCOMPRESS;
ALTER TABLE COMP_TEST COMPRESS;

Note: if you are enabling compression for an existing table, this will not affect the existing data inside table. Only the new data inserted will be compressed.

If you want to compress existing data inside the table, then you must perform move operation

ALTER TABLE COMP_TEST MOVE NOCOMPRESS;
ALTER TABLE COMP_TEST MOVE COMPRESS;

Compress partitions

When you use COMPRESS clause while creating a table with partitions, then all the partitions will be by default be COMPRESSED

CREATE TABLE COMP_PART_TEST(
  ID NUMBER(4),
  STD_NAME VARCHAR2(20),
  JOIN_DATE DATE NOT NULL,
)
COMPRESS
PARTITION BY RANGE (join_date) (
  PARTITION comp_part_1 VALUES LESS THAN (TO_DATE('01/01/2016','DD/MM/YYYY')),
  PARTITION comp_part_2 VALUES LESS THAN (MAXVALUE)
);

You can compress even individual partitions too

CREATE TABLE COMP_PART_TEST(
  ID NUMBER(4),
  STD_NAME VARCHAR2(20),
  JOIN_DATE DATE NOT NULL,
)
NOCOMPRESS
PARTITION BY RANGE (join_date) (
  PARTITION comp_part_1 VALUES LESS THAN (TO_DATE('01/01/2016','DD/MM/YYYY')) COMPRESS,
  PARTITION comp_part_2 VALUES LESS THAN (MAXVALUE)
);

Check partition compression

You can use below query to check each partition compression status

SELECT partition_name, compression
FROM   user_tab_partitions
WHERE  table_name = 'COMP_PART_TEST'
ORDER BY 1;

Change partition compress type

As we can change compression status for an existing table, we can even change compression status for an existing partition

ALTER TABLE comp_part_test MOVE PARTITION comp_part_2 COMPRESS;

See space savings with compress

Now that you have used compress option for a table, you must be able to see the block savings. First gather statistics

EXEC DBMS_STATS.gather_schema_stats(USER, cascade => TRUE);

Run below command to know exact block usage. Make sure to run below command before you compress a table so that you are able to see the difference in BLOCKS column

SELECT table_name,
       partition_name,
       compression,
       num_rows,
       blocks,
       empty_blocks
FROM   user_tab_partitions
WHERE  table_name = 'COMP_TEST'
ORDER BY 1;

Considerations

Make sure you keep in mind below considerations before going for table level compression:

  • Compression is not applied to LOB columns
  • Compression does speed up data reads
  • There is overhead on CPU for data loading
  • The default (basic compression) is used only for direct path load
  • To enable compression for all operations, use COMPRESS FOR ALL OPERATIONS clause
  • Do not use basic compression for OLTP operations

Was this article helpful?

Related Articles

Leave a Comment