所以我在Oracle 11Gr2中正确/使用索引时遇到了一些问题,我试图更好地理解我的解释计划如何与我的查询联系起来,以便我可以正确应用索引。运行以下查询时:
SELECT JLOG1.JLOG_KEY,
JLOG1.SRC_CD,
JLOG1.JRNL_AMT,
CASD.CONT_NO,
SUM (NVL (VJLOG.TDTL_AMT, 0)) TDTL_SUM
FROM GL_Journal_Logs JLOG1,
GL_JLOG_Details VJLOG,
CASE_DATA CASD
WHERE VJLOG.JLOG_KEY(+) = JLOG1.JLOG_KEY
AND CASD.CASE_KEY(+) = JLOG1.CASE_KEY
AND JLOG1.JRNL_CD = '0'
AND JLOG1.SRC_CD = '2'
AND JLOG1.ACCT_IF_CD = '0'
GROUP BY JLOG1.JLOG_KEY, JLOG1.SRC_CD,JLOG1.JRNL_AMT, CASD.CONT_NO
HAVING JLOG1.JRNL_AMT <> SUM (NVL (VJLOG.TDTL_AMT, 0));
我得到以下解释详情:
我可以理解,我的连接“keys”(JLOG_KEY或CASE_KEY)上的索引不一定适用,因为它是外部连接(或应该是吗?),但是在JLOG1上创建索引时(JRNL_CD,SRC_CD,ACCT_IF_CD) ),从技术上来说,这些会在我的“where”条款下生效吗?
我应该根据具体情况创建任何索引,还是有更好的方法呢?
答案 0 :(得分:2)
根据谓词中列的基数,可能会在GL_JLOG_DETAILS表上使用适当的索引,从而避免进行全表扫描。覆盖索引可能完全避免访问数据页:
ON GL_JOURNAL_LOGS (JRNL_CD,SRC_CD,ACCT_IF_CD,JLOG_KEY,CASE_KEY,JRNL_AMT)
(您可能希望在该索引中具有最具选择性谓词的列)
此外,您的查询可能能够有效地使用索引
ON GL_JLOG_DETAILS (JLOG_KEY, TDTL_AMT)
和
ON CASE_DATA (CASE_KEY, CONT_NO)
另外,请确保表和索引的统计信息是最新的。
此外,OUTER JOIN的(+)表示法可能会限制优化程序 Oracle现在支持ANSI样式连接,这可能允许优化器在提出执行计划方面有更大的自由度,例如
FROM GL_Journal_Logs JLOG1
LEFT
JOIN GL_JLOG_Details VJLOG ON VJLOG.JLOG_KEY = JLOG1.JLOG_KEY
LEFT
JOIN CASE_DATA CASD ON CASD.CASE_KEY = JLOG1.CASE_KEY
WHERE JLOG1.JRNL_CD = '0'
AND JLOG1.SRC_CD = '2'
AND JLOG1.ACCT_IF_CD = '0'