【问题标题】:Oracle indexes on RIGHT JOINRIGHT JOIN 上的 Oracle 索引
【发布时间】:2015-08-31 07:18:58
【问题描述】:

所以我在 Oracle 10g 中正确/任何使用索引时遇到了一些问题,我试图更好地了解我的解释计划如何与我的查询联系起来,以便我可以正确应用索引。运行以下查询时:

  SELECT *   FROM cns cns, cns_valid_status cvs, cns_valid_category cvc  
  WHERE cns.cns_cvs_code = cvs.cvs_code(+)  
  AND cns.cns_cvc_code = cvc.cvc_code(+) 
  and greatest(cns.start_date, nvl(cvs.start_date,'01-JAN-1900'),     nvl(cvc.start_date,'01-JAN-1900')) 
 < least(cns.end_date,nvl(cvs.end_date,'31-DEC-3999'), nvl(cvc.end_date,'31-DEC-3999'))  
 and nvl(cns.end_date,'31-DEC-3999') > TO_DATE(:V_From_Date,'DD-MON-RRRR HH24:MI:SS')
  order by cns.cns_ident,1,2; 

我得到以下解释细节:

  "PLAN_TABLE_OUTPUT"
  "Plan hash value: 3281260492"
  " "
  "------------------------------------------------------------------------------------------------"
  "| Id  | Operation                 | Name               | Rows  | Bytes    | Cost (%CPU)| Time     |"
  "------------------------------------------------------------------------------------------------"
  "|   0 | SELECT STATEMENT          |                    |    29 | 19604 |  1613   (1)| 00:01:11 |"
  "|   1 |  SORT ORDER BY            |                    |    29 | 19604 |  1613   (1)| 00:01:11 |"
  "|*  2 |   HASH JOIN OUTER         |                    |    29 | 19604 |  1612   (1)| 00:01:11 |"
  "|   3 |    MAT_VIEW ACCESS FULL   | CNS_VALID_CATEGORY |     4 |   280 |     2   (0)| 00:00:01 |"
  "|   4 |    VIEW                   |                    |   169K|    97M|  1610   (1)| 00:01:11 |"
  "|*  5 |     FILTER                |                    |       |       |            |          |"
  "|*  6 |      HASH JOIN OUTER      |                    |   169K|    33M|  1610   (1)| 00:01:11 |"
  "|   7 |       MAT_VIEW ACCESS FULL| CNS_VALID_STATUS   |     5 |   310 |     2   (0)| 00:00:01 |"
  "|*  8 |       MAT_VIEW ACCESS FULL| CNS                |   169K|    23M|  1607   (1)| 00:01:11 |"
  "------------------------------------------------------------------------------------------------"
  " "
  "Predicate Information (identified by operation id):"
   "---------------------------------------------------"
 " "
 "   2 - access(""CNS"".""CNS_CVC_CODE""(+)=""CVC"".""CVC_CODE"")"
 "       filter(GREATEST(""CNS"".""START_DATE""(+),NVL(""CVS"".""START_DATE""(+),TO_DATE(' "
 "              1900-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')),NVL(""CVC"".""START_DATE"",TO_DATE(' "
 "              1900-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))<LEAST(""CNS"".""END_DATE""(+),NVL(""CVS"".""E"
 "              ND_DATE""(+),TO_DATE(' 3999-12-31 00:00:00', 'syyyy-mm-dd "
 "              hh24:mi:ss')),NVL(""CVC"".""END_DATE"",TO_DATE(' 3999-12-31 00:00:00', 'syyyy-mm-dd "
 "              hh24:mi:ss'))))"
 "   5 - filter(NVL(""CNS"".""END_DATE"",TO_DATE(' 3999-12-31 00:00:00', 'syyyy-mm-dd "
 "              hh24:mi:ss'))>TO_DATE(:V_FROM_DATE,'DD-MON-RRRR HH24:MI:SS'))"
 "   6 - access(""CNS"".""CNS_CVS_CODE""(+)=""CVS"".""CVS_CODE"")"
 "   8 - filter(""CNS"".""CNS_CVS_CODE""(+) IS NOT NULL)"

我可以理解,我的连接列(cns_cvs_code,cns_cvc_code)上的索引不一定适用,因为它是一个外连接(或者应该是?)

在特定情况下我应该创建任何索引还是有更好的方法?

【问题讨论】:

    标签: oracle optimization oracle10g


    【解决方案1】:

    它是左或右外连接这一事实不会影响查询是否可以从索引中受益。

    在这种情况下,您可能会受益于 cvs.cvs_code 和 cvc.cvc_code 上的索引,但如果您要将两个表中的大部分行连接在一起,那么哈希连接将是最有效的机制。

    【讨论】:

    • 我尝试在上述列上建立索引,但解释计划是相同的。它正在执行全表扫描。你能建议其他方法吗?
    • 这里的问题之一是您没有向我们展示实际的查询。您可能正在查询视图,其中包含很多逻辑,包括一堆关于开始和结束日期的内容。因此,如果您显示实际查询,并且如果查询引用视图然后给出视图定义,那么也许您可以获得更多帮助。
    【解决方案2】:

    您可以尝试在以下位置添加索引:

    nvl(cns.end_date, date '3999-12-31')
    

    ...并在查询中使用该表达式:

    and nvl(cns.end_date, date '3999-12-31') > TO_DATE(:V_From_Date,'DD-MON-RRRR HH24:MI:SS')
    

    如果该表达式的选择性非常高,则可能会使用索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-13
      • 2015-12-31
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 2013-05-02
      相关资源
      最近更新 更多