Starting with Oracle database 9iR2 (Enterprise Edition!)
it is possible to create compressed heap organized tables and compressed table partitions as well as compressed materialized views.
This feature is very interesting for data warehouses because it can save a lot of disk space.
Compression has already been availble for b-tree indexes and index organized tables
since Oracle 8.1.5.
Here is an example:
LUTZ @10gR2 SQL > CREATE TABLE compress1 (col1 NUMBER, col2 VARCHAR2(30)) COMPRESS;
Table created.
LUTZ @10gR2 SQL > CREATE TABLE not_compress1
(col1 NUMBER,
col2 VARCHAR2(30));
Table created.
LUTZ @10gR2 SQL > SELECT table_name, compression
FROM user_tables;
TABLE_NAME COMPRESS
—————————— ——–
NOT_COMPRESS1 DISABLED
COMPRESS1 ENABLED
LUTZ @10gR2 SQL > BEGIN FOR i IN 1..100 LOOP
INSERT INTO not_compress1 VALUES(i, ‘value’ || i);
END LOOP;
FOR i IN 1..14 LOOP
INSERT INTO not_compress1 SELECT * FROM not_compress1;
END LOOP;
COMMIT;
END;
/
PL/SQL procedure successfully completed.
LUTZ @10gR2 SQL > SELECT COUNT(*) FROM not_compress1;
COUNT(*)
———-
819200
LUTZ @10gR2 SQL > SELECT COUNT(DISTINCT col2) FROM not_compress1;
COUNT(DISTINCTCOL2)
——————-
100
LUTZ @10gR2 SQL > INSERT /*+ APPEND*/
INTO compress1
SELECT *
FROM not_compress1;
819200 rows created.
SYSTEM @10gR2 SQL > SELECT extents,bytes, segment_name
FROM dba_segments
WHERE segment_name IN
(‘NOT_COMPRESS1′,
‘COMPRESS1′);
EXTENTS BYTES SEGMENT_NAME
———- ——- ——————-
27 12582912 COMPRESS1
30 15728640 NOT_COMPRESS1
Serial INSERT with append hint, as well as Parallel INSERT (with parallel hint) and also
Direct path insert with SQL*Loader into segments with compression enabled cause compression.
Inserting into a compressed table by using an ORDER BY CLAUSE for the column with lowest cardinality (least distinct values) incerases the compression rate!
With the COMPRESS clause is also possible to
create a table with a subselect as a compressed segment:
SYSTEM @10gR2 SQL > CREATE TABLE compress2 COMPRESS
AS SELECT * FROM lutz.not_compress1;
Table created.
SYSTEM @10gR2 SQL > CREATE TABLE to_be_compressed AS
SELECT * FROM lutz.compress1;
Table created.
SYSTEM @10gR2 SQL > SELECT extents,bytes, segment_name
FROM dba_segments
WHERE segment_name IN
(‘NOT_COMPRESS1′,
‘COMPRESS1′,
‘COMPRESS2′,
‘TO_BE_COMPRESSED’);
EXTENTS BYTES SEGMENT_NAME
———– ———– ——————————
27 12582912 COMPRESS1
30 15728640 NOT_COMPRESS1
30 15728640 TO_BE_COMPRESSED
27 12582912 COMPRESS2
It is also possibel to create a tablespace with compression as default:
SYSTEM @10gR2 SQL > CREATE TABLESPACE lutz_compress
DATAFILE ‘/u01/app/oracle/oradata/orcl/lutz_compress.dbf’
SIZE 10m AUTOEXTEND ON
DEFAULT COMPRESS;
Tablespace created.
SYSTEM @10gR2 SQL > CREATE TABLE lutz.not_compress2
TABLESPACE lutz_compress
AS SELECT * FROM lutz.not_compress1;
Table created.
SYSTEM @10gR2 SQL > SELECT extents,bytes, segment_name
FROM dba_segments
WHERE segment_name IN
(‘NOT_COMPRESS1′,
‘COMPRESS1′,
‘COMPRESS2′,
‘TO_BE_COMPRESSED’,
‘NOT_COMPRESS2′);
EXTENTS BYTES SEGMENT_NAME
————- —————- —————————–
27 12582912 COMPRESS1
30 15728640 NOT_COMPRESS1
30 15728640 TO_BE_COMPRESSED
27 12582912 COMPRESS2
27 12582912 NOT_COMPRESS2