2016-09-15 97 views
0

我使用SQL Server 2008中我有一個標量函數來抓住一個客戶端和輸出日期時間爲客戶端時區的時區。我在存儲過程的select語句中使用它。我注意到,使用函數或不使函數在性能上產生巨大差異,我嘗試檢查執行計劃並使用「統計時間,IO on」來運行存儲過程,以檢查是否有所作爲。標值功能選擇進行性能上的巨大差異

例如,這是調整時區查詢:

Declare @ClientID int 
Select @ClientID = 123 

select 
    abt.someID, myDB..adjustTimeZone(@ClientID, abt.dtDate) 
from 
    aBigTable as abt 
where 
    abt.dtDate > '2016-08-01' 
    and abt.dtDate < '2016-08-30' 

上面的代碼將返回約16K的記錄,並需要16秒才能完成。

我克隆記錄到九月公正,以確保它不會因爲任何緩存,然後我用另一種方式來調整時區,像下面的查詢:

Declare @ClientID int, @ZoneHourChange int 
select @ClientID = 123 

select @ZoneHourChange = (select hourOffSet from Client 
          where ClientID = @ClientID) 

select 
    abt.someID, DateADD(hour, @ZoneHourChange, abt.dtDate) 
from 
    aBigTable as abt 
where 
    abt.dtDate > '2016-09-01' 
    and abt.dtDate < '2016-09-30' 

上面的代碼返回16K記錄也,但只需要一半的時間。從執行計劃中我可以看到,成本是一樣的,並沒有涉及到平行性。什麼導致了巨大的差異?先謝謝你。

+2

一個進行查找每一行..其他不 – JamieD77

+0

你的意思是,該功能將在查找客戶端表的每一行的時區信息? – Jaaaaaaay

+1

是.. http://www.databasejournal.com/features/mssql/article.php/3845381/T-SQL-Best-Practices-150-Don146t-Use-Scalar-Value-Functions-in-Column-List-或-WEERE-Clauses.htm – JamieD77

回答

0

標量函數是一個東西應儘可能避免...

它能夠極大地加快你的查詢,如果你改變你的函數的inline TVF與一個單個列返回的表。

試試這個:兩種功能似乎做相同,但內聯TVF執行好得多......

CREATE FUNCTION dbo.TestScalar() 
RETURNS VARCHAR(100) 
AS 
BEGIN 
    RETURN 'test'; 
END 
GO 

CREATE FUNCTION dbo.TestInlineTVF() 
RETURNS TABLE 
AS 
    RETURN SELECT 'test' AS Result; 
GO 

SELECT dbo.TestScalar(); 

SELECT Result FROM TestInlineTVF(); 
GO 

DROP FUNCTION dbo.TestInlineTVF; 
DROP FUNCTION dbo.TestScalar; 
0

(可以包括該函數的代碼?)

如果它是一個SELECT <return> FROM table WHERE cols = @params然後你爲每一行都返回一次這個查詢,你最好跳過這個函數,然後在你的主查詢中加入表作爲連接。