oracle 索引壓縮(key compression)是oracle 9i 中引入的一項新特性。該特性可以壓縮索引或者索引組織表中的重復鍵值,從而節省存儲空間。非分區的unique 索引和non-unique(至少兩列)索引都能夠被壓縮。bitmap 索引不能夠進(jìn)行壓縮。 在oracle 索引壓縮中有幾個(gè)比較糾結的術(shù)語(yǔ),需要說(shuō)明一下。索引壓縮是通過(guò)將索引中的鍵值拆分成兩部分實(shí)現的,也就是grouping piece 也稱(chēng)作prefix 和 unique piece 也稱(chēng)作suffix 。grouping piece 是用來(lái)壓縮的被unique piece 共享的部分。如果鍵值不能提供unique piece,那么oracle 將會(huì )使用rowid 來(lái)唯一標識。只有B-tree 索引的葉子節點(diǎn)能夠被壓縮,分支節點(diǎn)不能夠被壓縮。索引壓縮是在單個(gè)block 中完成的,不能夠跨blocks進(jìn)行索引壓縮。grouping piece (prefix) 和 unique piece (suffix) 存儲在同一個(gè)索引 block 中。
具體prefix 和 suffix 是怎么劃分的呢?默認prefix 長(cháng)度等于索引列的數量減去1。當然我們可以人為控制prefix 的長(cháng)度,非唯一索引的最大prefix 長(cháng)度等于索引列的數量。唯一索引的最大prefix 長(cháng)度等于索引列的數量減去1。比如,假設索引有三個(gè)列:
默認的時(shí)候: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) 將會(huì )被壓縮至保留一份。
索引壓縮適合于那些鍵值重復率高的索引,這樣才能夠達到壓縮鍵值,節省存儲空間目的。
索引壓縮以后一個(gè)索引塊可以存放更多的鍵值,這樣當進(jìn)行fullindexscan,full fast index scan 的時(shí)候IO性能會(huì )更好,但是CPU的負載會(huì )增加,至于總體的性能就要看IO性能的提高和CPU負載增加那個(gè)是主要方面了。我不認為索引壓縮性能總是提高的,更多的意義在于節省存儲空間,減少I(mǎi)O時(shí)間。SQL> create
tableobjects1 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.--創(chuàng )建一個(gè)不壓縮的索引。
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 都是唯一的,所以沒(méi)有壓縮的空間,壓縮以后索引反而占用了更大的空間,還不如不壓縮。而objects2 中 object_id 都是重復的壓縮效果明顯。
除了創(chuàng )建的時(shí)候進(jìn)行索引壓縮,還可以在rebuild index 的時(shí)候指定索引壓縮和解壓縮。
SQL> alter index objects1_idx rebuild nocompress;
Index altered.
SQL> alter index objects1_idx rebuild compress;
Index altered.
注:壓縮也是會(huì )引入存儲開(kāi)銷(xiāo)的,只是很多時(shí)候壓縮節省的空間比壓縮需要的存儲開(kāi)銷(xiāo)更大,所以壓縮以后整體的存儲開(kāi)銷(xiāo)減小了。
compress 后面接的數字表示的是prefix 的深度,也就是需要用來(lái)壓縮的columns 的數量。