-2

結果を返すのに1秒か2秒かかる以下のsqlがあります。私はこのSQLをカーソルの中に500プラス時間入れて呼びます。私はこのクエリを書き直そうとしています。即興のSQLクエリ

SELECT Sum(CASE 
       WHEN UpdatedAdjustedOT IS NOT NULL 
        AND UpdatedAdjustedOT != '' 
        AND UpdatedAdjustedOT != '0' 
        THEN CONVERT(DECIMAL(18, 2), UpdatedAdjustedOT) 
       ELSE 0 
       END) AS OTHours 
    FROM tbl_OTAuthorization 
    WHERE EmployeeCodeFK = @EmployeeCode 
     AND month(OTDate) = Month(@FromDate) 
     AND year(OTDate) = Year(@FromDate) 

どのように私は

enter image description here

+2

、このいずれかを呼び出している外側のクエリは何ですか?これはそれ自身ではコストがかかりませんが、カーソルでそれを使用している場合は、それが何をしているのかを理解するために外側のクエリを参照する必要があります。 –

+0

私はカーソルにemployeelistを持っています。私はこのSQLでemployeecodeを渡すことによってothoursを見つけなければならない – StackUser

+1

問題はあなたのカーソルにあるので_all_コードを投稿してください。 –

答えて

0

このように見てまず、再書き込みWHERE句:

SELECT . . . 
FROM tbl_OTAuthorization 
WHERE EmployeeCodeFK = @EmployeeCode AND 
     OTDate >= DATEADD(day, 1 - DAY(@FromDate), @FromDate) AND 
     OTDate < DATEADD(month, 1, DATEADD(@FromDate, 1 - DAY(@FromDate), @FromDate)); 

第二に、作成テーブルの適切なインデックス:

CREATE INDEX tbl_OTAuthorization_2 ON tbl_OTAuthorization(EmployeeCodeFK, OTDate, UpdatedAdjustedOT); 

第3に、コードを修正して従業員と日付の間でループしないようにします。 1つのクエリでロジックを処理できるはずです。一般に、データベースを使用するパフォーマンスを最適化する場合は、カーソルを使用しないでください。

+0

ありがとうGordon Linoff – StackUser

1

より良い方法でこのクエリを書き直すか、私をお勧めしてください関数の結果にフィルターをかけません。これを交換する方法を探す:

AND month(OTDate) = Month(@FromDate) 
AND year(OTDate) = Year(@FromDate) 

このようなものに:

and OTDate >= the first day of the month for @FromDate 
and OTDate < the first day of the month following @FromDate 
0

これを試してみてください:

SELECT Sum(CONVERT(DECIMAL(18, 2), ISNULL(NULLIF(UpdatedAdjustedOT, ''), 0))) as OTHours 
    FROM tbl_OTAuthorization 
    WHERE EmployeeCodeFK = @EmployeeCode 
     AND month(OTDate) = Month(@FromDate) 
     AND year(OTDate) = Year(@FromDate) 
0
WHERE EmployeeCodeFK = @EmployeeCode 
    AND OTDate >= DATEADD(MONTH, DATEDIFF(MONTH, 0, @FromDate), 0) 
    AND OTDate < DATEADD(MONTH, 1, DATEADD(MONTH, DATEDIFF(MONTH, 0, @FromDate), 0))