[英]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.