分组上的SQL性能问题 - 超时

时间:2014-03-30 14:24:06

标签: sql sql-server-2012 grouping

我有一些数据 - 使用ContactID - 开始日期时间和结束日期时间列。 来源看起来像这样:

ContactID | A_DTStart        | A_DTEnd
      123 | 2014-03-04 23:43 | 2014-03-05 02:01
      121 | 2014-02-03 12:34 | 2014-02-03 14:44
      ...

我尝试对它们进行分组 - 但只有115条记录 - 运行查询大约需要38秒。

With
  AT1 As (Select
      EventLogUnpvt.ContactID,
      DateAdd(minute, -1 * IsNull(MasterLesson.DTstart, 0),
      Convert(date,EventLog.EventDate) +
      Convert(datetime,Convert(time,LandingLog.OffBlocks))) As A_DTstart,
      DateAdd(day, Case
        When
        (Convert(float,Convert(datetime,Convert(time,LandingLog.OffBlocks))) >
        Convert(float,Convert(datetime,Convert(time,LandingLog.OnBlocks)))) Then
        1 Else 0
      End, DateAdd(minute, IsNull(MasterLesson.DTend, 0),
      Convert(date,EventLog.EventDate) +
      Convert(datetime,Convert(time,LandingLog.OnBlocks)))) As A_DTend
    From
      LandingLog Inner Join
      EventLog On LandingLog.EventLogID = EventLog.ID Inner Join
      StudentLesson On EventLog.StudentLessonID = StudentLesson.StudentLessonID
      Inner Join
      MasterLesson On MasterLesson.ID = StudentLesson.LessonID Inner Join
      EventLogUnpvt On EventLogUnpvt.ID = EventLog.ID
    Where
      EventLog.EventDate > GetDate() - 2),
  a As (Select
      a.*,
      Row_Number() Over (Partition By a.ContactID Order By a.A_DTstart) As seqnum
    From
      AT1 a),
  ate As (Select
      a.ContactID,
      a.A_DTstart,
      a.A_DTend,
      a.seqnum,
      1 As grp,
      a.A_DTstart As grp_start
    From
      a
    Where
      a.seqnum = 1
    Union All
    Select
      a.ContactID,
      a.A_DTstart,
      a.A_DTend,
      a.seqnum,
      (Case When a.A_DTstart - ate.grp_start <= 14.0 / 24 Then ate.grp
        Else ate.grp + 1 End),
      (Case When a.A_DTstart - ate.grp_start <= 14.0 / 24 Then ate.grp_start
        Else a.A_DTstart End)
    From
      ate Join
      a On ate.ContactID = a.ContactID And ate.seqnum = a.seqnum - 1)
Select
  ate.*
From
  ate

嗯......问题是 - 我需要运行1000多条记录。我在那里暂停了。

此查询还有其他方法吗?

3 个答案:

答案 0 :(得分:1)

这是一种格式化的评论。你有这个:

Case
    When
    (Convert(float,Convert(datetime,Convert(time,LandingLog.OffBlocks))) >
    Convert(float,Convert(datetime,Convert(time,LandingLog.OnBlocks)))) Then
    1 Else 0

有什么理由不能简化到这个吗?

Case When LandingLog.OffBlocks > LandingLog.OnBlocks Then 1 Else 0

如果是这样,那将节省您的处理时间。

一般来说,您的整个查询可能比它需要的要复杂得多。但很难说,因为它不清楚它应该做什么。

答案 1 :(得分:1)

您可以使用sql management studio中的执行计划工具来帮助查找慢速部分。在查询窗口中右键单击,您将可以选择显示估计的计划和实际计划。这通常可以帮助您解决哪个部分存在问题。

结果数量只是查询处理时间的一个非常小的因素,通常只会影响它从服务器传输的速度。

SQL Server必须处理的记录数通常是罪魁祸首。如果您通过未编制索引的列加入记录并且这些源表很大,则速度很慢。如果此报告具有任何重要性,请对这些列进行索引我看到很多人都担心索引会如何影响插入/更新/删除,并忘记Read是我们执行的最常见的操作。

答案 2 :(得分:0)

我现在解决了 - 首先我创建了一个新表 - 从前两个CTE添加所有数据。 比我从这张表中运行最后一个查询... 现在所有这些都需要不到5秒。超过5000条记录。