I am using Oracle 12.2 version. I have SQL that has two filter condition to fetch NULL values from huge table. i have converted that IS NULL
to NVL (OFF_CODE, -1)=-1
and nvl(off_date,'01-JAN-1900')= '01-JAN-1900'
.
I have created functional based composite index on the two columns, then I taken explain plan that I pasted here. COST is reduced from 8 million to 122 now.
I was very happy after seeing this plan. but the SQL keep running for minutes. Before the change it was responding within 15 minutes. what could be the issue even after the cost is reduced the response is not quick? and how can I replace the IS NULL for better performance?
-------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 192 | 122 (1)| 00:00:01 |
| 1 | HASH GROUP BY | | 4 | 192 | 122 (1)| 00:00:01 |
| 2 | NESTED LOOPS | | 146 | 7008 | 121 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 148 | 7008 | 121 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| TABLE_NAME1 | 4 | 128 | 8 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | INDEX_TABLE_NAME1 | 4 | | 4 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | INDEX_TABLE_NAME2 | 37 | | 3 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID | TABLE_NAME2 | 37 | 592 | 36 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access(NVL("OFF_CODE_ID",(-1))=(-1) AND NVL("OFF_DATE",'01-JAN-1900')='01-JAN-1900')
6 - access("I"."ITEM_ID"="IGP"."ITEM_ID")
my query
SELECT /*+ index (i, INDEX_TABLE_NAME1) */
i.item_id,
SUM(coalesce(igp. DEPR_cost, 0) + coalesce(igp.act_dprctn_cost, 0)) depr_cost
FROM
TABLE_NAME1 i,
TABLE_NAME2 igp
WHERE 1 = 1
AND i.Item_id = igp.item_id
AND nvl(i.off_code_id,-1) = -1
AND nvl(i.off_date,'01-JAN-1900') = '01-JAN-1900'
GROUP BY i.item_id;<br/>
My index:
create index INDEX_TABLE_NAME1 on TABLE_NAME1( nvl( off_code_id,-1),nvl( off_date,'01-JAN-1900'));