简体   繁体   English

SQL : 此查询花费了太多时间

[英]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. SQL :这个查询花费了太多时间来处理 12 条记录,还为表明智地创建了事件索引。

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. CASE 在那里完全没有价值。 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.您加入的ad.AnchorDate与 CASE 的结果相等,但只有两个选项,其中一个是 NULL,它永远不会等于任何值(要查看某些内容是否为空,您需要使用 IS NULL),并且另一个是它自己。 Therefore you can easily use the between dates condition as the JOIN condition itself:因此,您可以轻松地使用日期之间的条件作为 JOIN 条件本身:

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:然后,您使用带有 ISNULL 值的 BETWEEN 子句,您可以将其替换为 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.我在您的 where 条件中观察到很少的文字。 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.如果您的查询作为过程/函数的一部分存在,请声明一个变量并分配值并将分配的值传递给 where 条件。

DECLARE @sp_Date DATETIME @sp_Date = GETDATE()声明@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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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