2016-05-03 15 views
-3

SQL: diese Abfrage dauert zu viel Zeit für 12 Datensätze, Ereignisindizes auch für Tabellen erstellt.SQL: Diese Abfrage benötigt zu viel Zeit

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

Bitte versuchen Sie und weitere Informationen geben. Was ist das Schema der Tabellen, die Sie referenzieren, was sind Ihre Indizes, wie viele Datensätze sind in der Tabelle, wie lange dauert es? – CathalMF

+2

Geben Sie den Ausführungsplan und die Indizes für die Tabelle an – TheGameiswar

+0

Überprüfen Sie den Ausführungsplan, damit Sie die erste Idee erhalten – Tassadaque

Antwort

1

Der CASE ist dort völlig wertlos. Sie fügen ad.AnchorDate mit dem Ergebnis aus der CASE gleich, aber es gibt nur zwei Optionen, von denen eine NULL ist, die nie gleich ist (um zu sehen, wenn etwas NULL ist, müssen Sie IS NULL verwenden), und die andere ist es selbst. Daher können Sie ganz einfach die zwischen Daten Bedingung wie die Bedingung JOIN verwenden selbst:

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

Dann verwenden Sie eine BETWEEN-Klausel mit einem ISNULL Wert, die Sie mit einem oder ersetzen:

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

Ich beobachte einige Literale in Ihrem Zustand. Die Literale sind Hauptverursacher beim Ausführen Ihrer Abfragen für Datenbanken mit hohem Volumen. Ein schneller Test wäre, dass Sie Ihre ursprüngliche Abfrage mit einer Datenbank von Millionen von Datensätzen ausführen und eine geänderte Abfrage (die Literale mit Variablen ersetzt - Beispiel unten) für dasselbe Datenvolumen ausführen. Sie werden bemerkenswerte Unterschiede in der Leistung feststellen.

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

Wenn Ihre Abfrage vorhanden als Teil einer Prozedur/Funktion ist, kann eine Variable deklarieren und den Wert zuweisen und den zugewiesenen Wert auf den in dem Zustand übergeben.

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)) 
Verwandte Themen