Sorry if the title is confusing, I am finding it difficult to clearly word my question.
Here is my scenario:
I have a table called SUBSCRIBERS that has two non-unique indexes. The columns indexed are AREA_ID and SUBSCRIPTION_DATE.
Now, I want to (efficiently) query for all subscribers in a specific area who have subscribed after a given date. Example SQL:
SELECT *
FROM subscribers
WHERE area_id = 'areaID'
AND subscription_date > to_date(some_date)
So let’s say to execute this query, Oracle first grabs all the rows with given areaID, and let’s say this is still a very large number of rows. Will Oracle be able to do a range scan on this subset of rows by subscription date? Or does the non-unique subscription_date index only apply to the FULL table, meaning that Oracle will have to do a linear scan over the subset?
Also, I’m not sure what the technical phrase would be to describe an index on a set that also applies to subsets. That would be a cool bonus if anyone knows the correct terminology.
Depending on the Oracle version, it is possible that both indexes could be used. However, in order to do this, Oracle would have to convert both b-tree indexes to bitmap indexes and do a bitmap merge on the two. This is not a particularly efficient operation, so it is not generally not a query plan that you’d want.
Oracle b-tree indexes work by storing the key and the ROWID in the table where the key occurs. In order to combine the indexes, Oracle first converts them to a bitmap index which is essentially a two-dimensional array that indicates which row meets which criteria. It can then combine the two bitmap indexes relatively easily. The complexity of this operation is in the initial conversion of the b-tree index into a bitmap index. In principle, nothing prevents Oracle from implementing a query plan that fetches all the ROWIDs from both indexes and perform an intersection of the two sets. I assume, however, that the bitmap conversion path is more efficient in general because that’s what Oracle implemented.
Jonathan Lewis has a section on bitmap conversions in his book Cost-Based Oracle Fundamentals.
It would almost certainly be more efficient to have a composite index on (
AREA_ID,SUBSCRIPTION_DATE). That would allow you to do an index range scan on the single composite index. Queries that just had a predicate onAREA_IDwould be able to use this composite index so the index onAREA_IDwould generally be made redundant.