【问题标题】:Cursors in SQL Server: High Performance PenaltySQL Server 中的游标:高性能损失
【发布时间】:2015-07-31 13:33:22
【问题描述】:

调用表

CallId |    Date | Time |   MemberID |  CallDuration
12     |    02.02.2015| 13:33:54|   3245|   234 |
13     |    02.02.2015| 13:37:24|   3245|   33  |

活动表

Date*********** Time*** MemberId    ***Activity
02.02.2015***   13:31:22*** 3245*** A
02.02.2015***   13:34:54*** 3245*** B

我的老板想知道当他们接到电话时,活动成员(员工)正在做什么(或之前的活动)。该数据存储在上面给出的两个表中。

我正在使用 Cursor 从 CallTable 中获取每一行,然后在循环中使用另一个游标来检索最后一个活动。 CallTable 中有大约 100 万行,处理它需要很长时间。 CallTable中没有基于CallID的Primary-Foreign key关系。

这里有人可以建议我如何通过 JOIN 实现这一目标并避免使用游标吗?

提前致谢

【问题讨论】:

  • 您的 SQL Server 版本是什么?
  • SQL Server 2008 R2标准版。
  • 对于 SS2008 Gordon 的查询应该是最好的。对于不同的方法,您需要 Cumulative Sum 或 Last_Value,SS2012 之前不支持这两种方法
  • 好的,谢谢你的信息。

标签: sql sql-server join cursors


【解决方案1】:

在 SQL Server 中,您可以使用相关子查询或使用 APPLY 来执行此操作。例如:

select c.*, a.activity
from calltable c outer apply
     (select top 1 a.*
      from activitytable a
      where a.memberId = c.memberId and
            a.datetime <= c.datetime
      order by a.datetime asc
     ) a;

这假定日期/时间在同一列中,这将是存储此值的正确方法。如果它们位于不同的列中,则类似(但更复杂)的逻辑会起作用。

为了提高性能,您需要在activitytable(memberid, datetime) 上建立索引。

【讨论】:

  • 如果你有一个单列要从activitytable“提取”,你可以做一个子查询而不是outer apply...
  • @stackoverflow.com/users/613130/xanatos,你能告诉我查询和子查询的样子吗?目前,我只需要从 activitytable 中提取一列。
  • @dbStudent 。 . .没有理由使用apply。但是,子查询方式基本相同。只需将子查询放在select 子句中并将a.* 更改为a.activity
【解决方案2】:

Lag and Lead 可能对您有所帮助

http://blog.sqlauthority.com/2013/09/22/sql-server-how-to-access-the-previous-row-and-next-row-value-in-select-statement/

这是一个 Northwind 小例子。

select * , DaysSincePreviousOrder = datediff(d , PreviousValue, OrderDate)  from (

  SELECT
LAG(p.OrderDate) OVER (ORDER BY p.CustomerID, p.OrderDate) PreviousValue,
p.CustomerID, p.OrderDate,
LEAD(p.OrderDate) OVER (ORDER BY p.CustomerID , p.OrderDate) NextValue
FROM dbo.Orders p where CustomerID = 'anatr' ) as derived1
where derived1.OrderDate = (select max(OrderDate) from dbo.Orders o where o.CustomerID = derived1.CustomerID)

GO

99.9% 的事情可以在没有光标的情况下完成。我在 10 年内写过一个游标......并且没有重新审视它,看看我是否可以重构。 我认为这是一个“命中几个数据库”类型的事情。但这只是规则的一个小例外……继续追求“基于集合”和非游标解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    相关资源
    最近更新 更多