05.11.2015 Views

Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

450<br />

CHAPTER 11 ■ INDEXES<br />

Select count(*)<br />

from T<br />

where gender = 'M'<br />

<strong>and</strong> location in ( 1, 10, 30 )<br />

<strong>and</strong> age_group = '41 <strong>and</strong> over';<br />

select *<br />

from t<br />

where ( ( gender = 'M' <strong>and</strong> location = 20 )<br />

or ( gender = 'F' <strong>and</strong> location = 22 ))<br />

<strong>and</strong> age_group = '18 <strong>and</strong> under';<br />

select count(*) from t where location in (11,20,30);<br />

select count(*) from t where age_group = '41 <strong>and</strong> over' <strong>and</strong> gender = 'F';<br />

You would find that a conventional B*Tree indexing scheme would fail you. If you wanted<br />

to use an index to get the answer, you would need at least three <strong>and</strong> up to six combinations<br />

of possible B*Tree indexes to access the data via the index. Since any of the three columns or<br />

any subset of the three columns may appear, you would need large concatenated B*Tree<br />

indexes on<br />

• GENDER, LOCATION, AGE_GROUP: For queries that used all three, or GENDER with LOCATION,<br />

or GENDER alone<br />

• LOCATION, AGE_GROUP: For queries that used LOCATION <strong>and</strong> AGE_GROUP or LOCATION alone<br />

• AGE_GROUP, GENDER: For queries that used AGE_GROUP with GENDER or AGE_GROUP alone<br />

To reduce the amount of data being searched, other permutations might be reasonable as<br />

well, to decrease the size of the index structure being scanned. This is ignoring the fact that a<br />

B*Tree index on such low cardinality data is not a good idea.<br />

Here the bitmap index comes into play. With three small bitmap indexes, one on each of<br />

the individual columns, you will be able to satisfy all of the previous predicates efficiently.<br />

<strong>Oracle</strong> will simply use the functions AND, OR, <strong>and</strong> NOT, with the bitmaps of the three indexes<br />

together, to find the solution set for any predicate that references any set of these three<br />

columns. It will take the resulting merged bitmap, convert the 1s into rowids if necessary,<br />

<strong>and</strong> access the data (if you are just counting rows that match the criteria, <strong>Oracle</strong> will just<br />

count the 1 bits). Let’s take a look at an example. First, we’ll generate test data that matches<br />

our specified distinct cardinalities—index it <strong>and</strong> gather statistics. We’ll make use of the<br />

DBMS_RANDOM package to generate r<strong>and</strong>om data fitting our distribution:<br />

ops$tkyte@ORA10G> create table t<br />

2 ( gender not null,<br />

3 location not null,<br />

4 age_group not null,<br />

5 data<br />

6 )<br />

7 as<br />

8 select decode( ceil(dbms_r<strong>and</strong>om.value(1,2)),

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!