2012-10-29 65 views
0

我試圖優化一個遞歸查詢的速度。完整的查詢運行15分鐘。 我試圖優化的部分需要3.5分鐘才能執行,並且在查詢中使用相同的邏輯兩次。使用排除列表優化遞歸查詢

說明:

Table Ret contains over 300K rows with 30 columns (Daily snapshot) 
Table Ret_Wh is the werehouse for Ret with over 5million rows (Snapshot history, 90days) 

datadate - 天信息記錄(如2012年10月1日)

statusA - 樣(紅色,藍色)一個狀態,一個帳戶可以有。

statusB - 帳戶可以擁有的不同狀態,如(大,小)。

狀態可以每天都在改變。

舊 - 帳戶上的整數年齡。如果帳戶上有付款,年齡可以增加/減少。否則每天加1。

帳號 - 帳號和行的主鍵。

在Ret中該帳戶是唯一的。
在RetWh帳戶是每個datadate唯一。

錢 - 計中計
兩個懲戒和Ret_Wh具有上述

查詢目標列出的列:從Ret_Wh,他在曾在一定範圍內的時代,在任何時候所有帳戶月,並且在該範圍內具有特定的狀態。
然後從這些結果中選擇與Ret中的帳戶匹配的特定年齡「今天」,無論其狀態如何。

我的目標:在某種程度上,這並不需要3.5分鐘

做這個

Pseudo_Code:

@sdt='2012-10-01' -- or the beginning of any month 
@dt = getdate() 

create table #temp (account char(20)) 
create table #result (account char(20), money money) 


while @sdt < @dt 
BEGIN 

insert into #temp 
select 
    A.account 

from Ret_Wh as A 
where a.datadate = @sdt 
    and a.statusA = 'Red' 
    and a.statusB = 'Large' 
    and a.old between 61 and 80 

set @sdt=(add 1 day to @sdt) 

END 
------ 

select distinct 
    b.account 
    ,b.money 

into #result 
from #temp as A 
join (Select account, money from Ret where old = 81) as B 
    on A.account=B.account 

我想創建Ret_Wh帳戶(稱之爲#shrinking_list)的一個獨特的列表。然後,在此期間,我將Ret_Wh加入#shrkining_list。在這段時間結束時,我從#shrinking_list中刪除了一個帳戶。然後一段時間,小的列表連接到Ret_Wh,從而加速查詢,因爲@sdt增加了1天。但是,我不知道如何將所選的完全相同的帳號傳遞給外部變量,以便我可以從#shrinking_list中將其刪除。

任何想法,或如何加快這一般?

+0

我編輯了您的標題。請參見「[應的問題包括‘標籤’,在他們的頭銜?(http://meta.stackexchange.com/questions/19190/)」,這裏的共識是「不,他們不應該」。 –

+0

謝謝約翰。我不知道這些標籤。雖然搜索會顯示標題,但標題的內容更多,而不相交標籤 - 並且標籤數量有限制。 – VISQL

+1

頂部標籤包含在SEO目的的標題中。我沒有任何建議。這已經在這裏得到了很好的思考。 –

回答

2

爲什麼使用遊標一次只能從@sdt到@dt獲取日期?

select distinct b.account, b.money 
from Ret as B 
join Ret_Wh as A 
    on A.account = B.account 
and a.datadate >= @sdt 
and a.datadate < @dt 
and a.statusA = 'Red' 
and a.statusB = 'Large' 
and a.old between 61 and 80 
where b.old = 81 
+0

光標幫助一次只查看1天的數據,僅考慮該特定日期的帳戶標準。謝謝你的幫助。當我看到這一點時,我認爲他們會成爲加入賬戶的一個問題,因爲在A看到一個「老」的範圍,並且我們正在看另一個範圍。但是,這工作得很好! – VISQL

+0

我繼承了這段代碼,很奇怪,即使是最後一個從事這個工作的人也沒有這樣看,儘管他幫助我重新審視了一下。這太快了! 8秒與舊版本的1:55比較。再次感謝 – VISQL

+0

那麼就像是如何不檢查正確的答案?但是你還在加入多天。使用遊標,您正在評估a.statusA ='Red'和a.statusB ='Large',並且a.old會在61到80之間多次而不是一次。 – Paparazzi