I have a large fact table with 300M rows and 50 columns in it. There are multiple reports over this table and each report uses only couple out of 50 columns from the table.
Each column in the fact table is indexed with BITMAP INDEX
. The idea is to use these indexes as a one-column version of the original table assuming that oracle could merge BITMAP INDEX
es easily.
If I use several columns from the table in WHERE
statement, I can see that oracle is able to merge these indexes effectively. There is BITMAP AND
operation in execution plan as expected.
If I use several columns from the table in SELECT
statement, I can see that depending on columns selectivity, oracle is either performing unneeded TABLE ACCESS
or BITMAP CONVERSION [to rowids]
and then HASH JOIN
of these conversions.
Is there any way to eliminate the HASH JOIN
in case of joining several BITMAP INDEX
es? Is there any hint in oracle to force BITMAP MERGE
when columns appear in SELECT
statement rather than WHERE
?
Intuitively it seems like the HASH JOIN
for BITMAP INDEX
es is unneeded operation in SELECT
statement taking into account it is indeed unneeded in WHERE
statement. But I couldn't find any evidence that oracle could avoid it.
Here are some examples:
SELECT a, b, c /* 3 BITMAP CONVERSIONs [to rowids] and then 2 unneeded HASH JOINS */
FROM fact;
SELECT a, b, c, d, e /* TABLE ACCESS [full] instead of reading all the data from indexes */
FROM fact;
SELECT a /* BITMAP INDEX [fast full scan] as expected*/
FROM fact
WHERE b = 1 and c = 2; /* BITMAP AND over two BITMAP INDEX [single value] as expected */
Are there any hints to optimize examples #1 and #2?
In production I use oracle11g but I tried similar queries on oracle12c and it look like in both versions of oracle behave the same.
After some research it looks like oracle12c is incapable of joining
BITMAP INDEX
es if they are used inSELECT
clause efficiently.There is no dedicated access path to join
BITMAP INDEX
es inSELECT
clause and soHASH JOIN
is used in this case.Oracle cannot use
BITMAP MERGE
access path in this case as it performsOR
operation between two bitmaps:Detailed analysis showed that only
HASH JOIN
was considered by cost optimizer in my case. I wasn't able to find any evidence thatBITMAP INDEX
es could be used efficiently inSELECT
statement. Oracle documentation suggests usingBITMAP INDEX
es only inWHERE
clause or joining fact to dimensions.In my case it is neither of the two.