2010-11-10 70 views
4

我使用FULL OUTER JOIN連接了2個表,這需要6分鐘的時間運行並提供輸出。Oracle SQL全外連接

SELECT * 
FROM tab1 FULL OUTER JOIN tab2 
ON tab1.id = tab2.id 
; 

我沒有使用LEFT OUTER聯盟JOIN和RIGHT OUTER JOIN同樣的事情。這個只需要15秒

SELECT * 
FROM tab1, tab2 
WHERE tab1.id (+) = tab2.id 

UNION 

SELECT * 
FROM tab1, tab2 
WHERE tab1.id = tab2.id (+) 
; 

有誰知道爲什麼發生這種情況?

+3

你是否檢查過這兩個查詢的查詢計劃? – 2010-11-10 18:37:35

+2

Oracle建議應避免使用傳統(+)語法。使用更通用的ISO標準LEFT/RIGHT JOIN語法,因此更適合SO等論壇。 – sqlvogel 2010-11-11 13:36:41

回答

3

您可能在兩個表中都有很多行,很少有共同的行,並且在有問題的列上沒有索引。

+0

@MacKay,我沒有索引,但我沒有很多共同的列... – mahen 2010-11-10 21:33:36

0

FULL OUTER JOIN與其他連接類型有所不同,因爲不能選擇單個前導表。

有效處理它的唯一方法是MERGE JOIN,但是,Oracle將不會選擇它。

對於您的查詢,哪個計劃的收益是Oracle

0

我在Oracle 9.2中體會到了這一點。可以通過將FULL OUTER JOIN分爲左外連接和右反連接(或其他?)來解決這個問題。

SELECT a.*, b.* 
from tableA a 
left outer join tableB b on (a.a = b.a) 
union all 
SELECT a.*, b.* 
from tableA a 
right outer join tableB b on (a.a = b.a) 
where a.a is null 

這是相當多的,你所提供的查詢,但使用UNION ALL及從該查詢的第二部分重複的,而不是使用UNION。有時我甚至無法獲得性能,需要進一步打破查詢,但不記得涉及到什麼。

對我來說,Oracle 10的情況似乎有所改善,但FULL OUTER JOIN不是我經常需要的東西,所以最近還沒有回到基準測試。

2

檢查解釋計劃。請記住,您指定的兩個查詢在邏輯上不相同。第二個查詢消除重複行(UNION),但第一個不行。這可能是性能差異解釋的一部分。

+0

其實,兩個結果集應該是相同的。完整的外連接將不會返回重複項,因爲每組連接行只能被找到一次。如果OP使用了union all,那麼每組連接的行將被返回兩次。 – Allan 2010-11-11 14:19:38

+1

@Allan:「兩個結果集應該是相同的」。只有當兩個表都沒有任何重複的行時,AND ID在至少一個表中才是唯一的。 – sqlvogel 2010-11-11 14:37:19

+0

好的,我可以看到這種情況是真的。我想,如果鍵不唯一,你必須使用具有三個查詢的'union all'來準確地重新創建外連接(內連接和兩個外連接,其中匹配集被刪除)。 – Allan 2010-11-11 14:50:17