左外连接上的Oracle索引

时间:2012-07-10 18:35:57

标签: oracle optimization oracle10g oracle11g

所以我在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));

我得到以下解释详情:enter image description here

我可以理解,我的连接“keys”(JLOG_KEY或CASE_KEY)上的索引不一定适用,因为它是外部连接(或应该是吗?),但是在JLOG1上创建索引时(JRNL_CD,SRC_CD,ACCT_IF_CD) ),从技术上来说,这些会在我的“where”条款下生效吗?

我应该根据具体情况创建任何索引,还是有更好的方法呢?

1 个答案:

答案 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'