Introduction To Reverse Key Indexes: Part I January 14, 2008
Posted by Richard Foote in Index Access Path, Oracle Cost Based Optimizer, Oracle Indexes, Reverse Key Indexes.trackback
Following on from the “8 things You May Not Know About Indexes”, #7 regarding Reverse Key Indexes requires a number of posts to do the subject justice. However, Part I will focus of the specific issue related to point # 7, namely:
“A REVERSE index can quite happily be used by the CBO to perform index range scans within an execution plan”.
Reverse Key Indexes are designed to resolve a specific issue, that being index block contention. Many indexes in busy database environments with lots of concurrent inserts (and in some scenarios updates and deletes as well) can suffer from index block contention (as highlighted by high levels of “buffer busy waits” and “read by other session” wait events for the index segments). Monotonically increasing indexes, such as Primary Keys generated by a sequence, are especially prone to contention as all inserts need to access the maximum “right-most” leaf block. This is of particular concern in RAC environments, where this “hot” index block needs to be accessed by all the instances and is being bounced around the various SGAs causing expensive block transfers between instances.
A solution is make the index a Reverse Key Index.
CREATE INDEX bowie_reverse_idx ON bowie(id) REVERSE;
A Reverse Key Index simply takes the index column values and reverses them before inserting into the index. “Conceptually”, say the next generated ID is 123456, Oracle will reverse it to 654321 before inserting into the index. It will then take the next generated ID 123457 and reverse it to 754321 and insert it into the index and so on. By doing this, inserts are spread across the whole index structure, ensuring the right most block is no longer the only index leaf block being hammered. Index contention is dramatically reduced or eliminated entirely.
Reverse Key Indexes address a specific problem but may in turn introduce a number of problems themselves.
One problem is the simple fact index entries are no longer sorted in their natural order. Value 123456 is no longer adjacent to value 123457 in the index structure, they’re likely to be found in completely different leaf blocks. Therefore a range predicate (such as BETWEEN 123450 and 123460) can no longer be found by a single index probe, Oracle would be forced to search for each specific index value separately as each value in the range is likely to be in differing leaf blocks.
This makes it all just too difficult and troublesome for the Cost Based Optimizer (CBO). As a result, the CBO totally ignores Reverse Key Indexes when processing Range Predicates (eg. BETWEEN, <, >, <=, >=, LIKE etc.). Even innocent looking range predicates such as “BETWEEN 123456 and 123457″, with just the 2 values of interest are ignored by the CBO. A 10053 trace shows how the CBO totally ignores Reverse Key Indexes and doesn’t even bother to cost such accesses when processing Range Predicate conditions.
In the above example and in scenarios where it’s possible and practical to convert range predicates, use an IN clause instead, e.g. “IN (123456, 123457)” as Oracle will convert this into an OR clause with each equality condition usable with the Reverse Key Index.
Oracle is also clever enough to identify equality conditions that may be written as a range scan (e.g. BETWEEN 123456 and 123456) and use a Reverse Key Index accordingly.
Hints won’t work either. You may be able to force Oracle into performing a Full Index Scan but it will not perform an Index Range Scan with a Range Predicate.
But doesn’t all this mean I’m wrong when I suggested a Reverse Key Index can be used by the CBO to use Index Range Scans.
No
I’ve only described how Oracle ignores the use of a Reverse Key Index for Range Predicates, however Index Range Scans are quite possible.
Remember, a Reverse Key Index will reverse all values and if two values happen to have the same value or two index entries happen to have the same leading column, then all such values are indeed stored together and are logically adjacent to one another.
For example, if the Reverse Key Index is Non-Unique, Oracle must perform an Index Range Scan, even for equality predicates. I discussed this in some detail when discussing the differences between a Unique and a Non-Unique Index. Even if the column or columns have a PK or a Unique Key Constraint, Oracle will still check the next index entry “just in case” there are indeed duplicate values. Also, although usually used for monotonically index columns, there’s nothing preventing you from creating a Reverse Key Index on a Non-Unique column and all duplicate values must reside together in the index structure. Therefore an equality search that uses any Non-Unique Reverse Key Index will generate an Index Range Scan access
But even Unique indexes can be used to perform an Index Range Scan.
If you have a multi-column Unique Index but not all columns are being searched (although the leading column must be known), then again, all index values with the same leading column (or columns) must be stored together in the Reverse Key Index and an Index range Scan can be performed for such equality conditions.
For some examples of what I’ve discussed see this Reverse Key Part I Demo.
So yes, a Reverse Key Index can indeed be used by the CBO to perform Index Range Scans.
There are also a number of other issues (and indeed myths) associated with Reverse Key Indexes that will be discussed in the fullness of time.
HI Richard,
You have in the 8th paragraph:
“One problem is the simple fact index entries are no longer sorted in their natural order”
Did you mean stored, rather than sorted – same letters different ordering!
cheers,
jason.
Hi Jason
Actually, to be perfectly honest I’m not entirely sure which word I meant to type !!
Either word kinda means what I trying to say as non-reverse indexes are both stored and sorted in their natural “binary” order within the index.
Whereas reverse indexes are neither stored or sorted in their natural binary order.
So you pick which word you prefer and makes the most sense and I’ll use it for you
Jason, funny coincidence. I would translate the sentence as “One problem is the simple fact index entries are no longer stored sorted according to their natural order.” But then again, I’m not a native speaker.
Richard, it started to dawn on me when I read the highlighted “predicates” and two paragraphs above the smiley I slapped my hand on my forehead. It’s so obvious. Man…
Thanks for handing me the crutch, Richard!
No worries Robert. After All, sometimes it’s those obvious things staring right in front of you that are hardest to spot …
Very Infomrative site, found it quite educational. I’ll definately bookmark this.
wonder can you have both an index and a reverse key index on the same column?
Hi Java
The short answer is no.
The slightly longer answer is why would you want to do such a thing when the idea of using a reverse key index is to reduced index contention. If you have both a reverse and a noreverse index, the reverse index would be pointless as you’ll still have the contention issues with the noreverse index. Therefore, Oracle allowing you to do so would make no sense.
However, the best answer is to suggest you simply try it out and find out yourself. Rather than wait potentially days for the answer, typing 3 short commands in a sqlplus session would give you the answer:
SQL> create table a (col1 number);
Table created.
SQL> create index a_idx on a(col1);
Index created.
SQL> create index a_rev_idx on a(col1) reverse;
create index a_rev_idx on a(col1) reverse
*
ERROR at line 1:
ORA-01408: such column list already indexed
There’s no need to wonder when it’s so easy to find out …
Hi,
How can we identify there is an Index Contenstion is High. Is there any formula to calculate the Index Contention apart from looking at High Buffer Busy Waits.
Raja
Hi Raja
There’s no formula as such. If you have high buffer busy waits and they’re a significant factor in causing response times or throughput times to be unacceptable, then you have a problem worth looking at. Looking a v$segment_statistics is also a good place to start for any general high contention issues.
Hi ,
This article is really gives good understanding of the reverse key indexes .
Thanks
Navodaya