2011-07-12 34 views
2

我有一個名爲DATEONLY標量值函數,返回DATEADD(DD,0,DATEDIFF(DD,0,@DATETIME)),就這樣我不同RowCounts:SQL服務器顯示使用標量值函數

CREATE FUNCTION [DBO].[DATEONLY] (@DATETIME DATETIME) 
RETURNS DATETIME 
BEGIN 
    RETURN DATEADD(DD, 0, DATEDIFF(DD, 0, @DATETIME)) 
END 

當我用我的功能選擇一個表,在SQL Server事件探查器計數比我直接使用DATEADD(DD,0,DATEDIFF(DD,0,@DATETIME))的高RowCounts數。

在我的Dropxbox的公用文件夾中,您可以找到一個script.sql,它可以重現我正在談論的內容,您還可以從我的SQL Server Profiler中找到Trace.trc。

script.sql:https://www.dropbox.com/s/gwbh54jqas7fhhc/script.sql

trace.trc:https://www.dropbox.com/s/gwbh54jqas7fhhc/Trace.trc

只是爲了簡化,看看下面的RowCounts。

SELECT DATEADD(DD,0, DATEDIFF(DD,0, INCOMING)) AS DATA, COUNT(*) AS SOULS 
FROM HELL 
GROUP BY DATEADD(DD,0, DATEDIFF(DD,0, INCOMING)) 

RowCounts = 6個

SELECT DBO.DATEONLY(INCOMING) AS DATA, COUNT(*) AS SOULS 
FROM HELL 
GROUP BY DBO.DATEONLY(INCOMING) 

RowCounts = 32

在我真實的情景,那些32行變成了幾百萬RowCounts。如果他們是同樣的事情,這是怎麼回事?如何優化,爲防止改變我的整個應用程序?

非常感謝!

回答

3

在sql server中,標量值用戶定義的函數執行效率不高 - 它實質上爲每個調用(表中的每一行)都執行一次單獨的執行調用。亞當Machanic對這個問題的描述標量UDF執行以及如何內嵌表值函數的執行速度會更快良好的post

可以重寫查詢以利用tvf中的邏輯,優化器使用與原始擴展查詢相同的查詢計劃執行,並在執行期間顯示相同的RowCounts = 5。

CREATE FUNCTION [DBO].[DATEONLY2] (@DATETIME DATETIME) RETURNS TABLE 
AS RETURN SELECT DATEADD(DD, 0, DATEDIFF(DD, 0, @DATETIME)) data 

select data, count(*) as souls 
from 
(SELECT (select data from dbo.dateonly2(incoming)) data 
FROM HELL) t 
GROUP BY data 
0

我會建議使用以下查詢

SELECT DATEADD(DD,0, DATEDIFF(DD,0, INCOMING)) AS DATA, COUNT(*) AS SOULS 
FROM HELL 
GROUP BY DATEADD(DD,0, DATEDIFF(DD,0, INCOMING)) 

你可以傳入列上創建索引,以避免性能淪落。