因此,我在Oracle10g中正确/任意使用索引时遇到了一些问题,我正在尝试更好地理解我的解释计划如何与我的查询绑定在一起,以便能够正确地应用索引。运行以下查询时:
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)上的索引不一定适用,因为它是一个外连接(或者它们应该应用吗?)
在这种情况下,我应该创建索引吗?或者有没有更好的方法呢?
发布于 2015-08-31 16:27:18
这是一个外连接,不管是left还是right,这并不影响查询是否可以从索引中获益。
在这种情况下,您可能会从cvs.cvs_code和cvc.cvc_code上的索引中受益,但是如果您要将两个表中的大多数行连接在一起,那么散列连接将是最有效的机制。
发布于 2015-08-31 21:17:56
您可以尝试在以下位置添加索引:
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')如果该表达式的选择性非常高,则可以使用索引。
https://stackoverflow.com/questions/32305862
复制相似问题