2010-03-22 70 views
0

下面的查詢時間超過3分鐘的運行,因爲表中包含大量的數據:在Oracle中比較兩個光標,而不是使用減號

SELECT RTRIM(LTRIM(A.HEAD)), 
     A.EFFECTIVE_DATE, 
    FROM TABLE_1 A 
    WHERE A.TYPE_OF_ACTION='6' 
    AND A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15) 

    MINUS 

    SELECT RTRIM(LTRIM(B.head)), 
     B.EFFECTIVE_DATE, 
    FROM TABLE_2 B 

在我們的系統中查詢就會被殺死,如果它正在運行更多比8秒鐘。有沒有辦法單獨運行查詢..輸入他們在遊標..比較,然後得到結果?這樣每個查詢將單獨運行,而不是作爲一個需要3分鐘的大規模查詢。

如何比較兩個遊標以模仿MINUS

回答

1

負是一組操作其中,第二個查詢的結果遠離第一個,也會刪除重複項,如果它們出現在第一個集合中。 因此,顯示的查詢將始終必須從TABLE_1構建完整的結果集,然後才能將其返回給用戶。

如果你可以肯定的是有在第一組trimemd頭/生效之日起不重複(或你不希望這樣的重複刪除),你可以嘗試

SELECT RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE, 
    FROM TABLE_1 A 
    WHERE A.TYPE_OF_ACTION='6' 
    AND A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15) 
    AND NOT EXISTS 
     (select 1 from table_2 b 
      where RTRIM(LTRIM(b.head)) = RTRIM(LTRIM(a.head)) 
      and b.effective_date = a.effective_date)) 

這種方式查詢可以更快地開始返回結果,特別是如果table_2非常小或者可以通過effective_date或head上的索引來訪問行。

PS。如果可以,請刪除RTRIM(LTRIM())位。

PPS。仍然不能保證它會在8秒內返回。這取決於table_1的大小,以及type_of_action和/或effective_date的索引。

補充:

你可以通過遊標

SELECT RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE, 
    FROM TABLE_1 A 
    WHERE A.TYPE_OF_ACTION='6' 
    AND A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15) 

,並忽略行,如果它返回

select 1 from table_2 b 
     where RTRIM(LTRIM(b.head)) = :1 
     and b.effective_date = :1 
     and rownum =1 

但肯定會需要更長的時間來完全執行。根據每次table_2檢查需要多長時間,可能會延長數小時(即小時)。不完全確定截斷時使用的標準(調用持續時間或打開的SQL遊標的持續時間),因此它可能會關閉外部遊標。根據table_1的大小/索引/內容,外部遊標可能仍然不會返回時間範圍內的第一行。

table_1,table_2中的行數和可用的索引數?

+0

但它不能使用遊標來完成? – Omnipresent 2010-03-23 14:07:59

0

MINUS與「第一個查詢的所有行,然後從該集合中刪除同樣在第二個查詢中的行」相同,因此您可以將第一個查詢的結果加載到數組中在內存中,然後遍歷第二個查詢結果,並逐個檢查它們對第一個查詢結果,如果它們存在,則將它們刪除。

雖然我不確定這會實際執行得更好(取決於很多事情)。您可能還需要考慮使用NOT EXISTS代替,並檢查性能,即

SELECT RTRIM(LTRIM(A.HEAD)), 
    A.EFFECTIVE_DATE, 
FROM TABLE_1 A 
WHERE A.TYPE_OF_ACTION='6' 
AND A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15) 
AND NOT EXISTS (
    SELECT 1 fFROM TABLE_2 B 
    WHERE RTRIM(LTRIM(A.HEAD)) = RTRIM(LTRIM(B.HEAD)) 
    AND A.EFFECTIVE_DATE = B.EFFECTIVE_DATE 
) 

,可能還需要對RTRIM(LTRIM(A.HEAD))的一些功能索引

相關問題