2009-10-29 83 views
1

我在星型模式中有一个超简单的查询。一个事实,两个维度。我已经证实我正在进行正确的连接。但是,当我执行查询计划时,我会在添加维度的步骤之前获得合并笛卡尔连接。什么可能导致合并笛卡尔连接

explain plan for 
select * from fact f 
inner join dim1 d1 
    on d1.id = f.d1_id 
inner join dim2 d2 
    on d2.id = f.d2_id 
where d1.code = 'A' and d2.code = 'B'; 

如果我更改为按维度ID而不是代码进行搜索,那么我的计划很好 - 没有笛卡尔。

explain plan for 
select * from fact f 
inner join dim1 d1 
    on d1.id = f.d1_id 
inner join dim2 d2 
    on d2.id = f.d2_id 
where d1.id= '1' and d2.id = '2'; 

任何想法可能导致笛卡尔发生?编辑: 我刚刚创建了表和索引今天。我将验证我是否对他们进行了“计算统计”,以确保所有数据都是最新的。

上现在的表,我已经编辑他们摆脱了笛卡尔的

的更多信息:

事实表:上dim1.id

位图索引

位图索引上dim2.id

(和其它更多的位图索引)

DIM1

ID上的唯一索引

代码上的位图索引 - 这是新的,但它似乎没有改变查询计划。

DIM2

的ID

唯一索引码 - 当我加入这个唯一索引,笛卡尔就走开了。

我的事实表有5000万条记录,dim1有44条记录,dim2有6条记录。所以我最初并没有在这样的矮桌上有索引。但是,向dim2添加唯一索引是摆脱了笛卡尔连接并将查询计划时间估计从5分钟减少到几秒。

回答

2

看起来“ID”比“代码”更有选择性,所以优化器决定在连接之后应用条件。尝试在代码中添加索引(如果可能,唯一的)会更改任何内容并为您提供更快的结果。

+0

谢谢!我无法使dim1.code具有唯一性,但我能够使dim2.code具有唯一性。这解决了它。感谢您的想法!但看起来这最终可能会导致我的问题。不是所有的模糊都有唯一的东西,除了身份证。 – user158017 2009-10-29 18:25:07

0

有几件事情可以在这里找到。

首先,执行计划如何根据估计的基数进行比较?这可能是计划变更的重要推动力。如果您的统计数据过期(尝试使用动态采样),那么维度结果集的基数可能会错误地很低或很高。其次,在后一个查询中,Oracle可能使用传递性将这些谓词直接应用于事实表,在这种情况下,它可能会更精确地估计该表中结果集的大小(尤其是动态采样或11g中的多列统计)。

解释计划对分析至关重要。