2010-10-01 32 views
1

這很難解釋,但我會嘗試。 query plan pic複雜查詢的CTE查詢計劃 - 同一個init查詢的三重運行 - 爲什麼?

當你在連接query_plan圖片中看到(這是查詢計劃「在同一個地方」查詢如下所述),有3幾乎相同的「塊」 - 我的問題是爲什麼呢?在我看來,當我有「全在一起」(見下文)查詢「初始化」塊(這是相當沉重的)是用不同的過濾器運行三次,而不是後來被SPOOLED和重複使用。

此查詢執行時間約爲45秒。 它查詢可以在一個形式呈現:

-- Complex "All in One place" Query 
WITH init as (
    Init1 complex query here -- (10 sec to run) if executed alone 
) 
, step1 as (select * from init .. joins... where ... etc), 
step2 as (select *, row_number() over(__condition__) as rn from step1 where _filter1_) 
, step3 as (select * from step2 where __filter2_), 
.... some more steps could be here .... 
select * 
into target_table 
from step_N; 
-- 45sec CPU time 

這裏最重要的是,我使用的第一步,第二步,...,內StepN表「和」條款順序 - 第1步使用INIT表,所以Step2使用Step1表,Step3使用Step2 Table等。我需要這個,因爲我在稍後用於過濾的每個步驟之後處理不同的排名。

如果變化這個複雜的CTE查詢(我把初始化查詢到表的結果,再處理其他步驟不改變):

-- Complex query separated from the rest of the query 
with Init as ( 
    The same Init1 complex query here 
) 
select * 
into test_init 
from init; 
-- 10sec CPU time 

with step1 as (select * from test_init .. joins... where ... etc), 
step2 as (select *, row_number() over(__condition__) as rn from step1 where _filter1_) , 
step3 as (select * from step2 where __filter2_), 
.... some more steps could be here .... 
select * 
into target_table 
from step_N; 
-- 5sec CPU time 

我的EXEC時間約15secs,這似乎是確定對我來說。因爲10秒是第一個難以改進的複雜查詢。

因此,我不能得到這個MS SQL Server 2005的行爲?有人可以向我解釋這個嗎?我想,這很有趣!

回答

1

看起來像優化器認爲它會更快地運行查詢三次不同的條件。優化器並不總是正確的。

實際上,使用臨時表來強制SQL Server首先執行整個複雜查詢是很常見的。通常情況下,你會使用一個臨時表,而不是test_init

insert into #temptbl select * from Init 

臨時表也使用SQL Server來存儲連接和子查詢的結果。使用臨時表格不會對性能產生負面影響。

+0

我們稍後使用表格有時用於質量保證目的。臨時表在適當的地方使用。嗯......有沒有辦法「告訴」MS SQL,最好把結果放在假脫機和重用中?寫一個計劃,提示,什麼? – zmische 2010-10-01 22:08:10

+0

@zmische - 對於計劃提示可能是可行的,但記住,spool無論如何都只是tempdb中的工作表。 – 2010-10-01 22:23:29

+0

是的,你說得對。但是我要在一個查詢中完成這項工作,而不需要額外的選擇。如果從MS SQL服務器的角度來看,更是如此。 %)Thx無論如何! – zmische 2010-10-01 22:59:54