I've got a table with an index on multiple columns, many of which are nullable.
CREATE UNIQUE INDEX
UX_MYTABLE_A_B_C_D_E
ON MYTABLE
("A", "B", "C", "D", "E")
And now from within C++ code, I'm trying to check this table and precisely hit the index. For each check, a different combination of the columns might be NULL.
My first attempt to do this query used NVL
, but this caused Oracle to ignore the index:
SELECT * FROM MYTABLE
WHERE NVL(A,0)=:1
AND NVL(B,0)=:2
AND NVL(C,0)=:3
AND NVL(D,0)=:4
AND NVL(E,0)=:5
(0 is not used in the data.) The query worked, but didn't hit the index; it was a full scan.
Next, I wrote custom C++ code which rebuilds the query each time, based on the search criteria, filling in IS NULL
or =:x
for each column:
SELECT * FROM MYTABLE
WHERE A IS NULL
AND B=:1
AND C IS NULL
AND D=:2
AND E=:3
This hits the index as well but requires a bunch of custom code and forces Oracle to parse a bunch of different varieties of the same basic query. It feels like this misses the point of bind variables, if I have to hand-assemble the query each time anyway. It would be much cleaner if I only had one query.
Is there a single query I can write which will work with any combination of NULL
s or not, without needing to add a new index, and will still always hit the index? (I realize I could add a functional index on NVL(A,0)
, NVL(B,0)
, etc., but again this feels horribly dirty for something which really ought to be simple! I'm trying to reuse my existing index, not create a new one.)