2017-10-02 11 views
0

私は、クエリしている次のようにCTEのパフォーマンスは(UDF)ユーザー定義関数より優れていますか?

SELECT c.CustomerName 
FROM Sales.Customer c 
WHERE Sales.ufnGetLastOrderDate(c.CustomerId) < DATEADD(DAY,-90,GETDATE()) 

Sales.ufnGetLastOrderDateユーザー定義関数(UDF)が定義されています

CREATE FUNCTION Sales.ufnGetLastOrderDate(@CustomerID int) 
RETURNS datetime 
AS 
BEGIN 
    DECLARE @lastOrderDate datetime 

    SELECT @lastOrderDate = MAX(OrderDate) 
    FROM Sales.SalesOrder 
    WHERE CustomerID = @CustomerID 

    RETURN @lastOrderDate 
END 

は、今私は、クエリのパフォーマンスを向上させたいです。

WITH cte(CustomerID, LastOrderDate) AS 
(
    SELECT 
     CustomerID, MAX(OrderDate) AS [LastOrderDate] 
    FROM 
     Sales.SalesOrder 
    GROUP BY 
     CustomerID 
) 
SELECT c.CustomerName 
FROM cte 
INNER JOIN Sales.Customer c ON cte.CustomerID = c.CustomerID 
WHERE cte.LastOrderDate < DATEADD(DAY,-90,GETDATE()) 

私の質問は、クエリがより優れた性能を持っている理由です:答えは、UDFをドロップすると、次のようにレポートの問合せをリライトするのですか?

+0

[SQLクエリを簡略化する関数を使用してパフォーマンスを大幅に向上させるかどうか](https://stackoverflow.com/questions/8008252/will-using-a-function-to-simplify-sql-query-massively) -imapact-performance) – GSerg

+0

両方実行し、どちらが良いかを確認しますか? –

+0

@JacobH、私はクエリのデータがありません。試験問題です。 – Bigeyes

答えて

0

CTEは本質的にビューです。 は、だからあなたの例では、CTEで、()内のクエリが最初に実行され、cte.CustomerID参加

SELECT c.CustomerName 
FROM (
    SELECT CustomerID, MAX(OrderDate) AS [LastOrderDate] 
     FROM Sales.SalesOrder 
    GROUP BY CustomerID) cte 
    INNER JOIN Sales.Customer c ON cte.CustomerID = c.CustomerID 
WHERE cte.LastOrderDate < DATEADD(DAY,-90,GETDATE()) 

に変換されるスカラー関数として実行されるバッチとして実行されますCustomerIDごとに1回、複数回

関連する問題