繁体   English   中英

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

[英]SQL : this query is taking too much of time

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;

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

然后,您使用带有 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))

我在您的 where 条件中观察到很少的文字。 在对大量数据库运行查询时,文字是主要的罪魁祸首。 快速测试是针对包含数百万条记录的数据库运行原始查询,并针对相同数据量运行修改后的查询(用变量替换文字 - 下面给出的示例)。 您会观察到性能的显着差异。

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

如果您的查询作为过程/函数的一部分存在,请声明一个变量并分配值并将分配的值传递给 where 条件。

声明@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