2

CustomerCustomerEventの2つのテーブルがあり、どちらも数百万行あります。 SQL Server 2000では、と呼ばれるUDFをデプロイしました。これはCustomerIDEventCodeという2つのパラメータに基づいてTRUEまたはFALSEを返します。SQL Server 2000と2005でのユーザー定義関数のパフォーマンス

SELECT dbo.fn_CustomerEvent(1345678, 'Music') 

UDFコードは次のとおりです。

CREATE FUNCTION [dbo].[fn_CustomerEvent](@CustomerID INT, @EviCode NVARCHAR(10)) 
RETURNS NVARCHAR(10) 
AS 
BEGIN 
    DECLARE @List NVARCHAR(10) 

    SELECT @List = CASE 
        WHEN COUNT(*) > 0 THEN 'TRUE' 
        ELSE 'FALSE' 
        END 
    FROM CustomerEvent 
    WHERE 
     CustomerID = @CustomerID 
     AND EviCode = @EviCode 

    RETURN @List 
END 

SQL Server 2000の上のパフォーマンスは素晴らしかったです。 3秒以内にTOP 5000行を返します。例えば、今、私たちは、SQL Server 2005の同じコード、同じUDFに移動している

SELECT TOP 5000 
    CustomerID, dbo.fn_CustomerEvent(1345678, 'Music') 
FROM [Table1] 

しかし、パフォーマンスは1分20秒3秒から劇的に低下します。

パフォーマンスを最適化するためにどこから正しい方向を指摘できますか?

答えて

1

UDFには大きな問題が1つあります。インデックスでは機能しません。コードを再利用してパフォーマンスを維持するには、通常、(インデックスを作成できる)計算カラムまたはビューを作成します。

+1

"インデックスでは動作しません"とはどういう意味なのでしょうか? UDFの実行計画では、索引を使用できます。 –

3

各行(すなわち、5000回)についてスカラーUDFが評価される。あなたは詳細を参照してくださいScalar functions, inlining, and performance: An entertaining title for a boring post

CREATE FUNCTION CustomerEvent (@CustomerID INT, 
           @EviCode NVARCHAR(10)) 
RETURNS TABLE 
AS 
    RETURN 
    (SELECT CASE 
       WHEN EXISTS(SELECT * 
          FROM CustomerEvent 
          WHERE CustomerID = @CustomerID 
           AND EviCode = @EviCode) THEN 'TRUE' 
       ELSE 'FALSE' 
      END) 

を一度呼び出し、変数

DECLARE @Result nvarchar(10) 
SELECT @Result = dbo.fn_CustomerEvent(1345678, 'Music') 

SELECT TOP 5000 
    CustomerID, @Result 
FROM [Table1] 

またはインラインTVFを使用することができます(と私もEXISTSの代わりCOUNTを使用する)で結果を格納

可能性がどちらかこの技術。

0
CREATE FUNCTION CustomerEvent (@CustomerID INT, 
           @EviCode NVARCHAR(10)) 
RETURNS TABLE 
AS 
    RETURN 
    (SELECT COALESCE((SELECT 'TRUE' FROM CustomerEvent 
        WHERE 
         CustomerID = @CustomerID 
         AND EviCode = @EviCode) 
       , 'FALSE')) 

インデックスを確認し、再構築して統計情報を更新してください。

+0

複数の行が 'WHERE'と一致すると、これはエラーをスローします。 –

関連する問題