2010-08-11 159 views
5

這裏是我的查詢:爲什麼此查詢會導致Oracle中的MERGE JOIN CARTESIAN?

select count(*) 
from email_prod_junc j 
inner join trckd_prod t5 on j.trckd_prod_sk = t5.trckd_prod_sk 
inner join prod_brnd b on t5.prod_brnd_sk = b.prod_brnd_sk 
inner join email e on j.email_sk = e.email_sk 
inner join dm_geography_sales_pos_uniq u on (u.emp_sk = e.emp_sk and u.prod_brnd_sk = b.prod_brnd_sk) 

解釋計劃說:DM_GEOGRAPHY_SALES_POS_UNIQ和EMAIL_PROD_JUNC之間

笛卡爾加入。

我不明白爲什麼,因爲每個表都有連接條件。

+4

合併連接笛卡爾實際上是否會導致性能問題,或者您只是不期望看到它?如果您正在加入的表中有一個表具有少量的行合併連接,則可以調用笛卡爾連接。另外,Oracle版本將會有所幫助,因爲從發佈到發佈,優化器都會發生很大的變化/改進。 – 2010-08-11 16:56:35

+0

是的,查詢花了一分鐘才返回笛卡爾連接。一旦我添加了訂購提示,它會在<1s內返回。這是Oracle 10g。 Trckd_Prod和Prod_Brnd是小表,其他3個非常大。 – 2010-08-12 17:15:11

+0

@MarkSherretta - 10g優化器被稱爲片狀,需要提示後續版本的優化器不需要。 11.1相當堅實 - 11.2更好。我沒有12個人的親身經歷,所以不能說這是怎麼回事。 – 2016-06-15 02:42:37

回答

5

我通過增加ordered提示解決了這個完整的加盟:

select /*+ ordered */ 

我從here

的資料。如果你指定的順序表,你希望他們加入並使用這個提示,Oracle將不會花時間試圖找出最佳的連接順序,它只會加盟因爲它們是在FROM子句中定義的。

+0

這種變化是否會影響性能? – Allan 2010-08-12 13:28:45

+0

是的,性能從> 1分鐘到<1秒。 – 2010-08-12 17:15:37

0

我會推測這是因爲最後一次內連接的on(x和y)條件。 Oracle可能不知道如何優化多語句條件,因此它會進行完全連接,然後根據事件後的條件對結果進行篩選。我不是很熟悉Oracle的解釋計劃,所以我不能說,有權威

編輯

如果你想檢驗這一假設,你可以嘗試更改查詢到:

inner join dm_geography_sales_pos_uniq u on u.emp_sk = e.emp_sk 
where u.prod_brnd_sk = b.prod_brnd_sk 

,看看是否消除了計劃

+1

感謝RMorrisey,但是這並沒有奏效,它導致了相同的執行計劃。 – 2010-08-11 14:11:19

1

不知道你的索引和完整的計劃,很難說爲什麼這是完全發生。我最好的猜測是EMAIL_PROD_JUNC和DM_GEOGRAPHY_SALES_POS_UNIQ相對較小,TRCKD_PROD(trckd_prod_sk,prod_brnd_sk)上有一個索引。如果是這樣的話,那麼優化器可能已經決定兩個較小表上的笛卡兒比兩次過濾TRCKD_PROD便宜。

相關問題