2014-02-18 75 views
1

我正在處理大量日期操作的查詢(Oracle 11g)。使用行生成器,我正在檢查另一個表中每個記錄的日期範圍內的每個日期。通過另一個查詢,我知道我的行生成器需要生成8500個日期,並且這個數量每年將增加365天。另外,我正在研究的表格大約有18000條記錄,而且這張表格預計每年會增加幾千條記錄。如何避免使用行生成器的昂貴的笛卡爾積

將行生成器連接到另一個表以獲取每個記錄的日期範圍時,會出現問題。 SQLTuning Advisor說,有一個昂貴的笛卡爾產品,這是有道理的,因爲查詢當前可以產生高達8500 x 18000條記錄。下面是其精簡形式的查詢,沒有所有的日期邏輯等:

with n as (
    select level n 
    from dual 
    connect by level <= 8500 
) 
select t.id, t.origdate + n origdate  
from (
    select id, origdate, closeddate 
    from my_table 
) t 
join n on origdate + n - 1 <= closeddate -- here's the problem join 
order by t.id, t.origdate; 

有沒有加入這兩個表沒有笛卡爾乘積的替代方法?

我需要計算每個記錄的運行時間,禁止週末和聯邦節假日,以便我可以對經過的時間進行排序。此外,表的分頁是在服務器端完成的,所以我們不能只加載到表中並對客戶端進行排序。

現在系統中記錄的最大年齡爲3656天,平均值爲560,因此它不像8500 x 18000那麼差。但它仍然不好。

我剛剛辭職加入了一個字段來存儲opendays,計算一次並存儲經過的時間,並創建一個計劃任務以每晚更新所有打開的記錄。

+0

你能解釋一下爲什麼你需要生成這麼多記錄? 8500 x 18000 = 15.300.000行,它必須很慢。 – krokodilko

+0

@kordirko,看看我上面的編輯。 – earachefl

回答

0

我認爲,如果你稍微改寫連接條件,你會得到更好的性能:

with n as (
    select level n 
    from dual 
    connect by level <= 8500 
) 
select t.id, t.origdate + n origdate  
from (
    select id, origdate, closeddate 
    from my_table 
) t 
join n on Closeddate - Origdate + 1 <= n --you could even create a function-based index 
order by t.id, t.origdate; 
+0

這確實有一點幫助,謝謝,但沒有足夠的地方。 – earachefl