Index Compression Part V: 12c Advanced Index Compression (Little Wonder) October 2, 2014Posted by Richard Foote in 12c, Advanced Index Compression, Index Compression, Oracle Indexes.
I’ve finally managed to find some free time in the evening to write a new blog piece 🙂
This will have to be the record for the longest time between parts in a series, having written Part IV of this Index Compression series way way back in February 2008 !! Here are the links to the previous articles in the series:
As I’ve previously discussed, compressing an index can be an excellent way to permanently reduce the size of an index in a very cost effective manner. Index entries with many duplicate values (or duplicate leading columns within the index) can be “compressed” by Oracle to reduce both storage overheads and potentially access overheads for large index scans. Oracle basically de-duplicates repeated indexed column values within each individual leaf block by storing each unique occurrence in a prefix section within the block, as I explain in the above links.
But it’s important to compress the right indexes in the right manner. If indexes do not have enough repeated data, it’s quite possible to make certain indexes larger rather than smaller when using compression (as the overheads of having the prefix section in the index block outweighs the benefits of limited reduction of repeated values). So one needs to be very selective on which indexes to compress and take care to compress the correct number of columns within the index. Oracle will only protect you from yourself if you attempt to compress all columns in a unique index, as in this scenario there can be no duplicate values to compress. This is all discussed in Part II and Part III of the series.
So, wouldn’t it be nice if Oracle made it all a lot easier for us and automatically decided which indexes to compress, which columns within the index to compress and which indexes to simply not bother compressing at all. Additionally, rather than an all or nothing approach in which all index leaf blocks are compressed in the same manner, wouldn’t it be nice if Oracle decided for each and every individual leaf block within the index how to best compress it. For those index leaf block that have no duplicate entries, do nothing, for those with some repeated columns just compress them and for those leaf blocks with lots of repeated columns and values to compress all of them as efficiently as possible.
Well, wish no more 🙂
With the recent release of Oracle Database 22.214.171.124, one of the really cool new features that got introduced was Advanced Index Compression. Now a warning from the get-go. The use of Advanced Index Compression requires the Advanced Compression Option and this option is automatically enabled with Enterprise Edition. So only use this feature if you are licensed to do so 🙂
The best way as always to see this new feature in action is via a simple little demo.
To begin, I’ll create a table with a CODE column that is populated with unique values:
SQL> create table bowie (id number, code number, name varchar2(30)); Table created. SQL> insert into bowie select rownum, rownum, 'ZIGGY STARDUST' from dual connect by level <= 1000000; 1000000 rows created.
I’ll now create a section of data within the table in which we have many repeated values:
SQL> update bowie set code = 42 where id between 250000 and 499999; 250000 rows updated. SQL> commit; Commit complete.
So I’ve fabricated the data such that the values in the CODE column are effectively unique within 75% of the table but the other 25% consists of repeated values.
From an index compression perspective, this index really isn’t a good candidate for normal compression as most of the CODE data contains unique data that doesn’t compress. However, it’s a shame that we can’t easily just compress the 25% of the index that would benefit from compression (without using partitioning or some such).
If we create a normal B-Tree index on the CODE column without compression:
SQL> create index bowie_code_i on bowie(code); Index created. SQL> select index_name, leaf_blocks, compression from user_indexes where table_name='BOWIE'; INDEX_NAME LEAF_BLOCKS COMPRESSION -------------------- ----------- ------------- BOWIE_CODE_I 2157 DISABLED
We notice the index consists of 2157 leaf blocks.
If we now try to use normal compression on the index:
SQL> alter index bowie_code_i rebuild compress; Index altered. SQL> select index_name, leaf_blocks, compression from user_indexes where table_name='BOWIE'; INDEX_NAME LEAF_BLOCKS COMPRESSION -------------------- ----------- ------------- BOWIE_CODE_I 2684 ENABLED
We notice that the compressed index rather than decrease in size has actually increased in size, up to 2684 leaf blocks. So the index has grown by some 25% due to the fact the index predominately contains unique values which don’t compress at all and the resultant prefix section in the leaf blocks becomes nothing more than additional overhead. The 25% section of the index containing all the repeated values has indeed compressed effectively but these savings are more than offset by the increase in size associated with the other 75% of the index where the index entries had no duplication.
However, if we use the new advanced index compression capability via the COMPRESS ADVANCED LOW clause:
SQL> alter index bowie_code_i rebuild compress advanced low; Index altered. SQL> select index_name, leaf_blocks, compression from user_indexes where table_name='BOWIE'; INDEX_NAME LEAF_BLOCKS COMPRESSION -------------------- ----------- ------------- BOWIE_CODE_I 2054 ADVANCED LOW
We notice the index has now indeed decreased in size from the original 2157 leaf blocks down to 2054. Oracle has effectively ignored all those leaf blocks where compression wasn’t viable and compressed just the 25% of the index where compression was effective. Obviously, the larger the key values (remembering the rowids associated with the index entries can’t be compressed) and the larger the percentage of repeated data, the larger the overall compression returns.
With Advanced Index Compression, it’s viable to simply set it on for all your B-Tree indexes and Oracle will uniquely compress automatically each individual index leaf block for each and every index as effectively as it can for the life of the index.