简体   繁体   中英

SQL : this query is taking too much of time

SQL : this query is taking too much of time for 12 records, event indexes also created for table wise.

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;

The CASE is completely worthless there. You are joining on ad.AnchorDate being equal with the result from the CASE, but there are only two options, one of which is NULL, which will never equal anything (to see if something is null you need to use IS NULL), and the other is itself. Therefore you can easily use the between dates condition as the JOIN condition itself:

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

Then, you are using a BETWEEN clause with an ISNULL value, which you can just replace with an OR:

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

I observe few literals in your where condition. The literals are major culprits while running your queries against high volume databases. A quick test would be that run your original query against a database of millions of records and run a modified query (replacing literals with variables - example given below) against same data volume. You'll observe a notable difference in performance.

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

If your query is present as part of a procedure / function, do declare a variable and assign the value and pass the assigned value to the where condition.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM