http://blog.itpub.net/26586127/viewspace-767703
oracle 索引压缩(key compression)是oracle 9i 中引入的一项新特性。该特性可以压缩索引或者索引组织表中的重复键值,从而节省存储空间。非分区的unique 索引和non-unique(至少两列)索引都能够被压缩。bitmap 索引不能够进行压缩。
在oracle 索引压缩中有几个比较纠结的术语,需要说明一下。索引压缩是通过将索引中
的键值拆分成两部分实现的,也就是grouping piece 也称作prefix 和 unique piece 也
称作suffix 。grouping piece 是用来压缩的被unique piece 共享的部分。如果键值不能
提供unique piece,那么oracle 将会使用rowid 来唯一标识。只有B-tree 索引的叶子节点
能够被压缩,分支节点不能够被压缩。索引压缩是在单个block 中完成的,不能够跨blocks
进行索引压缩。grouping piece (prefix) 和 unique piece (suffix) 存储在同一个索引 block 中。
具体prefix 和 suffix 是怎么划分的呢?默认prefix 长度等于索引列的数量减去1。当然
我们可以人为控制prefix 的长度,非唯一索引的最大prefix 长度等于索引列的数量。唯一
索引的最大prefix 长度等于索引列的数量减去1。比如,假设索引有三个列:
默认的时候:prefix (column1,column2) suffix (column3)
如果有以下几组键值(1,2,3),(1,2,4),(1,2,7),(1,3,5),(1,3,4),(1,4,4) 那么在prefix中重复的
(1,2),(1,3) 将会被压缩至保留一份。
索引压缩适合于那些键值重复率高的索引,这样才能够达到压缩键值,节省存储空间目的。
索引压缩以后一个索引块可以存放更多的键值,这样当进行full index scan,full fast index scan
的时候IO性能会更好,但是CPU的负载会增加,至于总体的性能就要看IO性能的提高和CPU
负载增加那个是主要方面了。
我不认为索引压缩性能总是提高的,更多的意义在于节省
存储空间,减少IO时间。
SQL> create
table objects1 as select object_id,object_name from dba_objects;
Table created.
SQL> create table objects2 as select 100 object_id,object_name from dba_objects;
Table created.
SQL> create table objects3 as select object_id,object_name from dba_objects;
Table created.
SQL> create index objects1_idx on objects1 (object_id) compress 1;
Index created.
SQL> create index objects2_idx on objects2 (object_id) compress 1;
Index created.
SQL> create index objects3_idx on objects3 (object_id);
Index created.--创建一个不压缩的索引。
SQL> select index_name,compression,leaf_blocks
2 from user_indexes
3 where index_name in ('OBJECTS1_IDX','OBJECTS2_IDX','OBJECTS3_IDX');
INDEX_NAME COMPRESS LEAF_BLOCKS
------------------------------ -------- -----------
OBJECTS1_IDX
ENABLED 222
OBJECTS2_IDX
ENABLED 112
OBJECTS3_IDX
DISABLED 161
我们可以看到对于objects1 和 objects3 因为object_id 都是唯一的,所以没有压缩的空间,
压缩以后索引反而占用了更大的空间,还不如不压缩。而objects2 中 object_id 都是重复的
压缩效果明显。
除了创建的时候进行索引压缩,还可以在rebuild index 的时候指定索引压缩和解压缩。
SQL> alter index objects1_idx rebuild nocompress;
Index altered.
SQL> alter index objects1_idx rebuild compress;
Index altered.
注:压缩也是会引入存储开销的,只是很多时候压缩节省的空间比压缩需要的存储开销更大,
所以压缩以后整体的存储开销减小了。
compress 后面接的数字表示的是prefix 的深度,也就是需要用来压缩的columns 的数量。