2016-05-03 8 views
-3

SQL:このクエリは、12個のレコードに対して時間がかかり過ぎます。イベントインデックスもテーブルワイズ用に作成されています。SQL:このクエリは時間がかかりすぎています

SELECT 
    p.AnchorDate, 
    'Active' StatusDefinition, 
    count(1) PatientCount, 
    6 AS SNO 
FROM 
    (SELECT DISTINCT 
     pp.PatientID, 
     ad.AnchorDate 
    FROM 
     PatientProgram pp WITH (NOLOCK) 
    INNER JOIN 
     #tblMonth ad ON ad.AnchorDate = CASE 
              WHEN ad.AnchorDate BETWEEN DATEADD(dd, - (DAY(pp.EnrollmentStartDate) - 1), pp.EnrollmentStartDate) 
         AND EOMONTH (ISNULL(pp.EnrollmentEndDate, '9999-12-31')) 
               THEN ad.AnchorDate 
               ELSE NULL 
             END 
    WHERE NOT EXISTS (SELECT 1 
         FROM #ManagedPopulation m 
         WHERE m.tKeyId = pp.ProgramID) 
     AND pp.ProgramID != 4331) p 
GROUP BY 
    p.AnchorDate; 
+1

試してみて、より多くの情報を教えてください。参照しているテーブルのスキーマとは何ですか?インデックスは何ですか?テーブル内のレコード数はどのくらいですか? – CathalMF

+2

テーブルの実行計画とインデックスを提供 – TheGameiswar

+0

実行計画を見直してください最初の考えを与える – Tassadaque

答えて

1

ケースは完全に無価値です。 ad.AnchorDateはCASEの結果と同じですが、2つのオプションしかありません。そのうちの1つはNULLです。何も決して等しいものではありません(何かがヌルであるかどうかを見るためにIS NULLを使用する必要があります)それ自体です。したがって、あなたは簡単に結合条件自体との間の日付の条件を使用することができます。

INNER JOIN #tblMonth ad 
ON ad.AnchorDate BETWEEN 
    DATEADD(dd, - (DAY(pp.EnrollmentStartDate) - 1), pp.EnrollmentStartDate) 
    AND 
    EOMONTH (ISNULL(pp.EnrollmentEndDate, '9999-12-31')) 

その後、あなたはあなただけのORで置き換えることができますISNULL値、とBETWEEN句を使用している:

INNER JOIN #tblMonth ad 
ON ad.AnchorDate >= DATEADD(dd, - (DAY(pp.EnrollmentStartDate) - 1), pp.EnrollmentStartDate) 
    AND 
(pp.EnrollmentEndDate IS NULL OR ad.AnchorDate<=EOMONTH (pp.EnrollmentEndDate)) 
0

私はあなたのwhereの条件でリテラルをほとんど観察しません。リテラルは、大量のデータベースに対してクエリを実行している間、大きな犯人です。クイックテストは、元のクエリを数百万のレコードのデータベースに対して実行し、同じデータボリュームに対して変更されたクエリを実行することです(リテラルを変数に置き換えます - 例を参照)。パフォーマンスに顕著な違いが見られます。あなたのクエリがプロシージャ/ファンクションの一部として存在している場合

WHEN ad.AnchorDate BETWEEN DATEADD(dd, - (DAY(pp.EnrollmentStartDate) - 1), pp.EnrollmentStartDate) 
         AND EOMONTH (ISNULL(pp.EnrollmentEndDate, '9999-12-31')) 

は、変数を宣言し、値を代入し、WHERE条件に割り当てられた値を渡します。

DECLARE @sp_Date DATETIME @sp_Date = GETDATE()

WHEN ad.AnchorDate BETWEEN DATEADD(dd, - (DAY(pp.EnrollmentStartDate) - 1), pp.EnrollmentStartDate) 
         AND EOMONTH (ISNULL(pp.EnrollmentEndDate, @sp_Date)) 
関連する問題