2017-04-05 26 views
1

私の問題は、実行に時間がかかりすぎるクエリを作成したことです。SQL Serverクエリの最適化

City | Department | Employee | Attendance Date | Attendance Status 
------------------------------------------------------------------------ 
C1  | Dept 1  | Emp 1  | 2016-01-01  | ABSENT 
C1  | Dept 1  | Emp 2  | 2016-01-01  | LATE 
C1  | Dept 2  | Emp 3  | 2016-01-01  | VACANCY 

だから私は、同じデータが含まれており、従業員の総数(すなわち、各ステータスの割合を決定するために、後にSSRSのプロジェクトで私を提供しています)が含まれて列を追加するビューを作成したいです。

私は、部門と日付による単純な選択フィルタリングを作成する関数を作成しました。

と、この機能を使用するクエリです:

SELECT  City, Department, Employee, [Attendence Date], [Attendance Status], [Get Department Employees By Date](Department, [Attendence Date]) AS TOTAL 
FROM   attendenceTable 

これは、関数である:

CREATE FUNCTION [dbo].[Get Department Employees By Date] 
(
    @deptID int = null, 
    @date datetime = null 
) 
RETURNS nvarchar(max) 
AS 
BEGIN 
    declare @result int = 0; 
    select @result = count(*) from attendenceTable where DEPT_ID = @deptID and ATT_DATE_G = @date; 
    RETURN @result; 

END 

問題は、クエリを実行するために(私は非常に長い時間を意味する)時間がかかりすぎるということです。 最適化の提案?

+0

?どのようにデータをフィルタリングするのですか? –

+2

機能コードも含めてください。ありがとうございます –

+0

データはどのくらいの頻度で変更されますか?これはピークの夜に実行できますか?データベースはMS SQLですか?インデックスはありますか? – lloyd

答えて

3

関数はスカラー関数であり、結果セット(〜600,000)の各行に対して1回実行され、既知のパフォーマンス・キラーです。これは、インラインテーブル値関数に書き換えることができ、またはロジックが他の場所で必要とされていない場合は、簡単なグループは、&は十分であろう参加回数:

あなたがそのテーブルに持っているかどうインデックス
WITH EmployeesPerDeptPerDate 
      AS (SELECT DEPT_ID , 
         ATT_DATE_G , 
         COUNT(DISTINCT Employee) AS EmployeeCount 
       FROM  attendenceTable 
       GROUP BY DEPT_ID , 
         ATT_DATE_G 
      ) 
    SELECT A.City , 
      A.Department , 
      A.Employee , 
      A.[Attendence Date] , 
      A.[Attendance Status] , 
      ISNULL(B.EmployeeCount, 0) AS EmployeeCount 
    FROM attendenceTable AS A 
      LEFT OUTER JOIN EmployeesPerDeptPerDate AS B ON A.DEPT_ID = B.DEPT_ID 
                  AND A.ATT_DATE_G = B.ATT_DATE_G;