2016-02-12 21 views
0

我有從我們的大型機數據庫中拉出的日曆表並保存爲本地Access表。這個表格的歷史可以追溯到20世紀30年代(我知道我們至少在一個地方使用了50年代),結果創造了31萬條記錄。此日曆表有3個感興趣的字段:來自日曆表(MS Access中)的下一個/上一個營業日的SQL

Bus_Dt - 每天,不只是工作日。主鑰匙
Bus_Day_Ind - 表示該日是否爲股市的有效營業日。
Prir_Bus_Dt - 前一個工作日。包含一些錯誤(約50),都是舊的。

我寫了一個查詢來檢索當前日曆日當天或之後的第一個工作日,但它運行速度極慢。 (5分鐘以上)我已經檢查了showplan輸出,並且看到它正在通過一個x-join運行,這個x-join在30k +記錄表之間給出了近1000萬的解決方案空間(和日期比較)。然而,實際的任務並不難,並且可以通過使用簡單排序的最短時間內的卓越來舒適地執行。

我的問題是,有什麼辦法來解決查詢的糟糕表現,或者這是SQL的固有失敗? (DB2在大型機上運行也很慢,儘管並不那麼令人擔憂)拋出問題和其他所有問題。其次,如果我信任prir_bus_dt,我能更好地實現嗎?或者限制日期範圍(aka,「cheat」)或其他任何我還沒有想到的技巧?

SQL:

SELECT TE2Clndr.BUS_DT AS Cal_Dt 
    , Min(TE2Clndr_1.BUS_DT) AS Next_Bus_Dt 
FROM TE2Clndr 
    , TE2Clndr AS TE2Clndr_1 
WHERE TE2Clndr_1.BUS_DAY_IND="Y" AND 
    TE2Clndr.BUS_DT<=[te2clndr_1].[bus_dt] 
GROUP BY TE2Clndr.BUS_DT; 

顯示計劃:

Inputs to Query 
Table 'TE2Clndr' 
Table 'TE2Clndr' 
End inputs to Query 
01) Restrict rows of table TE2Clndr 
     by scanning 
     testing expression "TE2Clndr_1.BUS_DAY_IND="Y"" 
     store result in temporary table 
02) Inner Join table 'TE2Clndr' to result of '01)' 
     using X-Prod join 
     then test expression "TE2Clndr.BUS_DT<=[te2clndr_1].[bus_dt]" 
03) Group result of '02)' 

同樣,問題是,是否可以變得更好(快),或者是這已經是好得不能再好?

+0

既然你已導入表導入Access和表是不太可能被可怕的刷新往往你可以簡單地添加NEXT_BUS_DT柱,使用一切必要手段來填充它(即使它是不是特別有效),然後直接查詢「下一個業務日期」值。這也有助於避免稍後「查詢必須使用可更新的記錄集」問題。 –

+0

這是我的默認計劃,在我的「作弊」之前解決了這個問題。我儘量避免「讓表格」類型的執行,因爲每一步都是一個可以被遺忘的項目 - 尤其是當它每年僅使用一次的時候。我也關心這個問題背後的「理論」,因爲我有時在DB2服務器上使用相同的邏輯,而我沒有表能力。 DB2獲得的基本查詢是正確的,但是當它是一個大型任務中的子查詢時,它有時會感到困惑,並因此產生一個糟糕的查詢計劃。 (無法看到來自DB2的計劃,也禁用。) – Et314159

回答

-1

怎麼樣這種方法

select min(bus_dt) 
from te2Clndr 
where bus_dt >= date() 
and bus_day_ind = 'Y' 

This是我date()參考代表當前日期

+0

啊 - 我認爲(正常情況下)我有點不清楚。我打算將此作爲一個「翻譯表」,以便從其他地方獲取日曆日期列表,並將其轉換爲適當的日期。所以我希望在理論上有一個列表,最多可以應用到約30個日期,而不僅僅是當前日期。儘管只在我實際需要的那些日期運行日期邏輯,但您已經給出了我的想法,而不是構建整個翻譯表,其中大部分翻譯表在任何給定時間都不使用。查詢優化器甚至可能爲我做! – Et314159

+0

我想象一個只有兩個字段的翻譯查詢:[Calendar_Date]和[Next_Business_Date]。如果Calendar_Date是營業日,那麼這兩個值是相等的。 (「Next」有點讓人誤解,因爲它可能仍然是同一天,但我對這個概念缺乏一個更好的詞)。問題標題是指如何在前一個工作日使用具有相反符號的相同查詢,以及下一個工作日。 – Et314159

+0

@ Et314159 - *「'下一步'有點誤導,因爲它可能仍然是同一天,但我缺乏這個概念更好的詞。」* - 我建議你開始稱它爲「有效的生意日期」。 –

0

我有一個新的查詢是同樣的工作要快得多,但它取決於prir_bus_dt場(有一些錯誤)。這也不是一個偉大的理論,因爲之前的工作日並不一定在每個人的日曆上都可用。所以我不認爲這個「答案」只是一個答案。

新建查詢:

SELECT TE2Clndr.BUS_DT as Cal_Dt 
    , Max(TE2Clndr_1.BUS_DT) AS Next_Bus_Dt 
FROM TE2Clndr 
INNER JOIN TE2Clndr AS TE2Clndr_1 
    ON TE2Clndr.PRIR_BUS_DT = TE2Clndr_1.PRIR_BUS_DT 
GROUP BY TE2Clndr.BUS_DT;