2009-10-29 39 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中的多列統計)。

解釋計劃對分析至關重要。