2015-08-31 59 views
0

因此,我在Oracle 10g中正確/使用任何索引時遇到了一些問題,並且試圖更好地理解我的解釋計劃與我的查詢的關係,以便可以應用索引正確。當運行下面的查詢:Oracle ROW JOIN上的索引

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)指標不一定會看申請因爲它是一個外連接(或者它們應該是這樣嗎?)

我應該在給定情況下創建任何索引嗎?還是有更好的方法來做到這一點?

回答

0

它是外連接,左或右,不影響查詢是否可以從索引中受益。

在這種情況下,您可能會受益於cvs.cvs_code和cvc.cvc_code上的索引,但是如果您將兩個表中的大部分行連接在一起,那麼散列連接將是最有效的機制。

+0

我試着索引上述的列,但解釋計劃是一樣的。它正在執行全表掃描。你能推薦一些其他的方式嗎? – hema

+0

那麼這裏的一個問題就是你沒有向我們展示實際的查詢。你大概在查詢視圖,這些視圖中有很多邏輯,包括一堆關於開始和結束日期的內容。所以如果你顯示實際的查詢,並且如果查詢引用了視圖然後給出視圖定義,那麼也許你可以得到更多的幫助。 –

0

您可以嘗試添加索引:

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') 

如果表達的選擇性是非常高的,則指數可能使用。