I have been trying to optimize a query by adding several indices. I was successful in most of them but there is this one query where the column I have created was never used. Query looks something like this:
SELECT DISTINCT
  c.containername
  , hml.qty
  , CAST(hml.txndate AS TIMESTAMP) txndate
  , hml.comments
  , e.fullname
  , 'ICO' txn
FROM con c
JOIN hml hml ON c.containerid = hml.historyid
JOIN emp e ON hml.employeeid = e.employeeid
WHERE hml.comments LIKE '%ICO%'
      AND hml.txndate >= to_date(:ddate, 'MM/DD/YYYY HH:MI:SS PM')
      AND e.notes IN ('DBP', 'FTD', 'MH', 'SUPERVISOR')
ORDER BY CAST(hml.txndate AS TIMESTAMP);
Execution Plan
    Plan hash value: 267728100
---------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                      |   116 | 14616 |   248K  (1)| 00:49:40 |
|   1 |  SORT ORDER BY                   |                      |   116 | 14616 |   248K  (1)| 00:49:40 |
|   2 |   HASH UNIQUE                    |                      |   116 | 14616 |   248K  (1)| 00:49:40 |
|   3 |    NESTED LOOPS                  |                      |       |       |            |          |
|   4 |     NESTED LOOPS                 |                      |   116 | 14616 |   248K  (1)| 00:49:40 |
|*  5 |      HASH JOIN                   |                      |   116 | 11252 |   248K  (1)| 00:49:37 |
|*  6 |       TABLE ACCESS FULL          | EMPLOYEE             |     8 |   304 |    25   (0)| 00:00:01 |
|*  7 |       TABLE ACCESS BY INDEX ROWID| HISTORYMAINLINE      | 38373 |  2210K|   248K  (1)| 00:49:37 |
|*  8 |        INDEX RANGE SCAN          | HISTORYMAINLINEMX005 |   347K|       |  1248   (1)| 00:00:15 |
|*  9 |      INDEX UNIQUE SCAN           | CONTAINER450         |     1 |       |     1   (0)| 00:00:01 |
|  10 |     TABLE ACCESS BY INDEX ROWID  | CONTAINER            |     1 |    29 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("HML"."EMPLOYEEID"="E"."EMPLOYEEID")
   6 - filter("E"."NOTES"='DBP' OR "E"."NOTES"='FTD' OR "E"."NOTES"='MH' OR 
              "E"."NOTES"='SUPERVISOR')
   7 - filter("HML"."COMMENTS" IS NOT NULL AND "HML"."COMMENTS" LIKE '%ICO%')
   8 - access("HML"."TXNDATE">=TO_DATE(:DDATE,'MM/DD/YYYY HH:MI:SS AM'))
   9 - access("C"."CONTAINERID"="HML"."HISTORYID")
Cost is 248,283. Same with the cost before i put on the index. Additionally, when i change the hml.comments LIKE '%ICO%' to hml.comments = '%ICO%', cost improves really well (only 14!) because the index I have created is used. Unfortunately, I still have to used LIKE since I don't know the position where the tag ICO is used on the comments column.
Is there a way I can have the query be improved? I am using Oracle 11g and the hml table has a total rows of 40,193,106 by the way. Thanks in advance to all who will take time to answer.
