为什么此查询会导致Oracle中的MERGE JOIN CARTESIAN?

时间:2010-08-11 13:57:36

标签: oracle

这是我的问题:

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之间进行笛卡尔连接。

我不明白为什么,因为每个表都有一个连接条件。

3 个答案:

答案 0 :(得分:4)

我通过添加ORDERED提示解决了这个问题:

select /*+ ordered */

我从here

获取了相关信息

如果您按照希望它们加入的顺序指定表并使用此提示,Oracle将不会花时间尝试找出最佳连接顺序,它只会在FROM子句中按顺序连接它们。 / p>

答案 1 :(得分:2)

在不了解您的索引和完整计划的情况下,很难说为什么会发生这种情况。我最好的猜测是EMAIL_PROD_JUNC和DM_GEOGRAPHY_SALES_POS_UNIQ相对较小,并且TRCKD_PROD(trckd_prod_sk,prod_brnd_sk)上有索引。如果是这种情况,那么优化器可能已经确定两个较小的表上的笛卡尔比比过滤TRCKD_PROD两倍便宜。

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

并查看是否会消除计划中的完整联接