如何在计划中使用'merge join cartesian'优化oracle查询?

时间:2012-03-01 16:59:34

标签: sql oracle oracle10g query-optimization

查询:

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

分组太慢......它是如何加速的?

3 个答案:

答案 0 :(得分:1)

只要您有CARTESIAN JOIN,就可能表示您在编写查询时错过了连接条件。请检查你的联接,看看你是否错过了。

答案 1 :(得分:1)

b中所有合并列中nullnot null b.sectb.m_codea的所有行都匹配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... )

此外,最好让您的统计数据保持最新状态(尽管我不足以让Oracle专家知道如何做到这一点)。


编辑:这在功能上是相同的,可能会更好:

{{1}}

这将确保至少有一个值匹配。

答案 2 :(得分: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

分享并享受。