10

爲什麼查詢版本2如此之快?爲什麼當我(手動)將表值函數的結果緩存在臨時表中時,查詢執行速度會如此之快?

我懷疑DB引擎多次調用表值函數「GetUsageStatistic」,那麼有沒有辦法告訴引擎「GetUsageStatistic」是確定性的,應該只調用一次?

查詢版本1

--Takes ~10 minutes 
select * 
from RosterLevel r 
left join GetUsageStatistics(@mindate, @maxdate) usage on r.UserID = usage.UserID; 

查詢版本2

--Takes ~10 seconds 
select * into #usage from GetUsageStatistics(@mindate, @maxdate); 
select * 
from RosterLevel r 
left join #usage on r.UserID = #usage.UserID; 
+0

'GetUsageStatistics'的外觀是什麼樣的?它是單個查詢還是多個查詢導致單個結果集? – 2011-06-02 21:43:44

+0

GetUsageStatistics是一個內聯表值函數(ITVF),它從GetWeeklyUsage中進行選擇,GetWeeklyUsage本身就是一個從GetDailyUsage(也是ITVF)中進行選擇的ITVF。它基本上是一個確定性ITVF的簡單鏈,每個鏈都會在其輸出列中返回SUM,AVG和COUNT函數的聚合結果的級別。 – Triynko 2011-06-02 21:48:53

+0

@Triynko - 絕對值得兩個查詢的實際執行計劃,並比較它們,看看您的多次執行TVF理論是否正確。 – 2011-06-02 21:50:20

回答

1

正如在評論中提到的,最好的答案是什麼分析執行計劃吐了出來。除此之外,你的直覺可能是正確的,但除了SQL Server自動嘗試的任何緩存之外,在你提供的查詢提示方式中,沒有什麼可以提供的,以表明函數是確定性的,但是歡迎嘗試在Query Hints MSDN page中提到了幾件事情。我的第一次測試可能會借鑑Table Hints

+0

標籤「SQL」是微軟的標籤嗎? – Tim 2011-06-07 00:26:37

+1

@Tim:不是。但事實上,很多人似乎都認爲它是如此。假設SQL Server的另一個原因可能是OP的腳本顯然是T-SQL(來自'#'-names)。但實際的原因可能是OP在他們的一個評論中提到了SSMS。 – 2011-06-07 06:33:27

+0

@Tim:@Andriy權利 - '顯而易見'是主題,因爲它只適用於那些已經知道TSQL的樣子,而SSMS是MS的人。但是,除了這種勢利外:-),你是對的,這不是一個普通的SQL問題,它是一個TSQL問題,就誰能回答這個問題以及誰會對它進行搜索感興趣,它擺在首位。 – Chains 2011-06-14 17:35:49

0

如果您在第一個示例中使用該函數,則會多次調用它 - 對於RosterLevel表中的每條記錄都會調用一次。它每次都會返回一個(可能)不同的表,具體取決於連接字段。

如果您在第二個示例中使用該函數,則僅調用一次該函數。從那裏,表變量在內存中,你不必一遍又一遍的閱讀。

相關問題