I know Oracle sometimes “judges” that it’s better to perform full table scan as oppose to index scan, however still being in a “learning stage”, I’m just trying to get a better understanding of “when” oracle will determine the best route. For example, I have simple query:
Select *
FROM GLMV_JOURNAL_LOGS JLOG
INNER JOIN GLMV_Transact_Details TDTL
ON TDTL.TR_REF_NO = JLOG.TR_REF_NO
AND TDTL.SCAT_KEY = JLOG.Scat_key
AND TDTL.CASE_KEY = JLOG.CASE_KEY
AND TDTL.TR_CD = JLOG.TR_CD
INNER JOIN FUND_DESC FDDC
ON FDDC.FD_DESC_ID = TDTL.FD_DESC_ID
INNER JOIN FD_RATES FDRT
ON FDRT.FDRT_KEY = TDTL.FDRT_KEY
INNER JOIN BEN_TYPES BNTP
ON BNTP.BNTP_KEY = FDRT.BNTP_KEY
WHERE JLOG.JRNL_CD = '0'
AND JLOG.SRC_CD = '2'
AND JLOG.MKEY_FD_NUM <> 0
AND NVL(JLOG.TMOV_KEY, -1) > 0
AND NVL(JLOG.ORIG_SCAT_KEY, 1) = 1
AND TDTL.STAT_CD <> '4'
AND NVL(TDTL.ORIG_SCAT_KEY, 1) = 1
The join on FD_RATES is joining on PK value, which I also created a corresponding index on GLMV_Transact_Details in thinking that a full table scan would be prevented, however, based on the explain plan below, it’s not, even after I’ve performed index rebuild and gather table stats, the outcome is still the same:

Now if I go into my query and add the following where clause:
AND FDRT.FDRT_KEY = 100
The index will kick in of course, but I guess I’m curious as to why it’s not when doing an inner join…. any tips??
The optimizer has estimated the cost of the full table scan on FD_RATES as 106. The join this feeds into has an estimated cardinality of 416, as does the other row source feeding that join. If we were to replace the hash join with a nested loop, doing a unique index (PK) lookup for each row, the cost would be at least 1, probably 2 or 3, for each iteration of the loop, and we think there will be 416 iterations, so that would be a cost of at least 416, probably double or triple that, which is much more than the estimated cost of doing the full table scan.
Now, the estimates could be wrong. The main thing to look at, in my experience, is the cardinalities shown in the plan. If these are reasonably accurate, then there’s a good chance that Oracle has picked reasonably efficient join order and access paths — not necessarily the most efficient, but close.
If you want to try to force an index scan to see how it performs, I believe the hint you want would be: