Below is a simple query running against oracle 9.2.0.7. The parameters come from an application designed for old Boreland drivers. The application has performance issues due to following query takes more than 1hr to run. Prior the data was less but after years the data has grown. The tables has all the required indexes but indexes are taking into effect which accurate values are passed, otherwise it doing a full table scan. How can I improve the performance of the query I want to force query to use index.Below i posted all the required information.Please help Below I also have explain plan
SELECT V.*,W.FIRSTNAME || ' ' || W.LASTNAME as personname,
S.LOGINID as SUPERVISOR,
W.COMMROOMID
FROM VOILOG V,LLSWORKER W,LLSWORKER S
WHERE V.INTLLSID = W.LLSID(+) AND W.SUPERVISORID = S.LLSID(+)
AND TRUNC(V.ENTRYDATE) BETWEEN '01-JAN-15' AND '04-MAR-15'
AND W.COMMROOMID like '%9999%'
AND V.VOISUBCATID like '%'
AND S.LOGINID like '%'
AND V.ENTEREDBYLLSID like '%'
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 155 | 22785 | 1101 |
|* 1 | FILTER | | | | |
|* 2 | HASH JOIN | | 155 | 22785 | 1101 |
|* 3 | HASH JOIN | | 162 | 22680 | 1043 |
|* 4 | TABLE ACCESS FULL| VOILOG | 162 | 17496 | 985 |
|* 5 | TABLE ACCESS FULL| LLSWORKER | 1551 | 49632 | 57 |
|* 6 | TABLE ACCESS FULL | LLSWORKER | 1862 | 13034 | 57 |
--------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_DATE('01-JAN-15')<=TO_DATE('04-MAR-15'))
2 - access("W"."SUPERVISORID"="S"."LLSID")
3 - access("V"."INTLLSID"="W"."LLSID")
4 - filter(TRUNC("V"."ENTRYDATE")>='01-JAN-15' AND
TRUNC("V"."ENTRYDATE")<='04-MAR-15' AND
"V"."VOISUBCATID" LIKE '%'
AND TO_CHAR("V"."ENTEREDBYLLSID") LIKE '%')
5 - filter(TO_CHAR("W"."COMMROOMID") LIKE '%9999%')
6 - filter("S"."LOGINID" LIKE '%')
But when my query has exact values like below
SELECT V.*,W.FIRSTNAME || ' ' || W.LASTNAME as personname,
S.LOGINID as SUPERVISOR,
W.COMMROOMID
FROM VOILOG V,LLSWORKER W,LLSWORKER S
WHERE V.INTLLSID = W.LLSID(+) AND W.SUPERVISORID = S.LLSID(+)
AND TRUNC(V.ENTRYDATE) BETWEEN '01-JAN-15' AND '04-MAR-15'
AND W.COMMROOMID like '9999'
AND V.VOISUBCATID like '%'
AND S.LOGINID like '%'
AND V.ENTEREDBYLLSID like '%'
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 147 | 239 |
|* 1 | FILTER | | | | |
|* 2 | TABLE ACCESS BY INDEX ROWID | VOILOG | 1 | 108 | 181 |
| 3 | NESTED LOOPS | | 1 | 147 | 239 |
| 4 | NESTED LOOPS | | 1 | 39 | 58 |
|* 5 | TABLE ACCESS FULL | LLSWORKER | 1 | 32 | 57 |
|* 6 | TABLE ACCESS BY INDEX ROWID| LLSWORKER | 1 | 7 | 1 |
|* 7 | INDEX UNIQUE SCAN | XPKLLSWORKER | 1 | | |
|* 8 | INDEX RANGE SCAN | XIEINTLLSID1 | 198 | | 2 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_DATE('01-JAN-15')<=TO_DATE('04-MAR-15'))
2 - filter(TRUNC("V"."ENTRYDATE")>='01-JAN-15' AND
TRUNC("V"."ENTRYDATE")<='04-MAR-15' AND "V"."VOISUBCATID" LIKE '%'AND
TO_CHAR("V"."ENTEREDBYLLSID") LIKE '%')
5 - filter(TO_CHAR("W"."COMMROOMID") LIKE '9999')
6 - filter("S"."LOGINID" LIKE '%')
7 - access("W"."SUPERVISORID"="S"."LLSID")
8 - access("V"."INTLLSID"="W"."LLSID")
TRUNC(V.ENTRYDATE) BETWEEN '01-JAN-15' AND '04-MAR-15'into:V.ENTRYDATE BETWEEN to_date('01-JAN-15', 'dd-mon-yy' ) AND to_date('04-MAR-15', 'dd-mon-yy' ) + 1, this expresion prevents oracle from using an index on V.ENTRYDATE, if this index exists.TRUNC()is what is preventing the index's being used onENTRYDATE(which it will unless there is a function-based index on that column).