SQL:这个查询占用了太多时间

时间:2016-05-03 08:57:23

标签: sql sql-server

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;

2 个答案:

答案 0 :(得分:1)

CASE在那里毫无价值。你加入的ad.AnchorDate与CASE的结果相同,但是只有两个选项,其中一个是NULL,它永远不会等于任何东西(看看是否为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))

答案 1 :(得分:0)

我在你的情况下观察到很少的文字。在针对高容量数据库运行查询时,文字是主要的罪魁祸首。一个快速测试是针对数百万条记录的数据库运行原始查询,并针对相同的数据量运行修改后的查询(用变量替换文字 - 下面给出的示例)。你会发现性能上有显着差异。

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

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

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