2012-03-01 87 views
3

查詢:如何在計劃中使用'merge join cartesian'優化oracle查詢?

select max(b.counter) as counter, 
     b.m_group, 
     b.m_code, 
     a.s_id, 
     s.id_sk 
    from tbl_various a, tbl_map b, tbl_sheet s 
where coalesce(b.part, a.part) = a.part 
    and coalesce(b.nums, to_number(a.nums)) = a.nums 
    and coalesce(b.interc, a.interc) = a.interc 
    and coalesce(b.segment, a.segment) = a.segment 
    and coalesce(b.acountry, a.acountry) = a.acountry_midas 
    and coalesce(b.orig_name, a.orig_name) = a.orig_name 
    and coalesce(b.fact, a.fact) = a.fact 
    and b.sect is not null 
    and s.m_code = b.m_code 
group by b.m_group, b.m_code, a.s_id, s.id_sk; 

計劃:

SELECT STATEMENT, GOAL = ALL_ROWS  86763 1   169 
HASH GROUP BY       86763 1   169 
    HASH JOIN        86762 1   169 
    TABLE ACCESS FULL TBL_MAP   2  1717  92718 
    MERGE JOIN CARTESIAN     79688 300133251 34515323865 
    TABLE ACCESS FULL TBL_SHEET  5  912   18240 
    BUFFER SORT       79682 329274  31281030 
    TABLE ACCESS FULL TBL_VARIOUS  87  329274  31281030 

集團通過太慢......它是如何加快?

+1

您是否嘗試過表'tbl_map'的外連接? – 2012-03-01 17:17:21

+1

順便說一下,'to_number(a.nums)'部分有什麼意義? – Martin 2012-03-01 19:06:36

回答

1

任何行b已在所有coalesce'd列null值,是b.sectnot nullb.m_code將在a匹配任何行,即做一個笛卡兒連接。

我的猜測是,這是造成這個問題。即使b中實際上沒有這樣的行,優化程序可能會進行笛卡爾連接。

您可以通過添加

and (b.part is not null or b.nums is not null or b.intersec is not null or etc...) 

另外要避免這種情況,它總是一個好主意,讓您的統計上的最新(雖然我沒有足夠的甲骨文專家知道如何要做到這一點)。


編輯:這是功能相同,可能會更好地工作:

and (b.part = a.part or b.nums = a.nums or b.intersec = a.intersec or etc...) 

這將確保至少有一個值匹配。

0

鑑於在WHERE子句中存在那些COALESCE調用,我真的不知道這是否可以加快。然而,希望能夠永恆......嘗試添加以下索引並看看會發生什麼:

TBL_VARIOUS 
    PART 
    NUMS 
    INTERC 
    SEGMENT 
    ACOUNTRY_MIDAS 
    ORIG_NAME 
    FACT 
    S_ID 

TBL_MAP 
    PART 
    NUMS 
    INTERC 
    SEGMENT 
    ACOUNTRY 
    ORIG_NAME 
    FACT 
    SECT 
    M_CODE 
    (M_GROUP, M_CODE) 

TBL_SHEET 
    M_CODE 
    ID_SK 

分享和享受。

1

任何時候當你有一個CARTESIAN JOIN,它可能表明你在編寫查詢時錯過了一個連接條件。請檢查你的連接,看看你是否錯過了。