【问题标题】:SQL Server - Strategy for Long-Running Aggregate QuerySQL Server - 长时间运行聚合查询的策略
【发布时间】:2014-01-23 23:47:27
【问题描述】:

场景:

  • ASP.Net 4.5 Web 应用程序可捕获用户对视频的“投票”。
  • 每次投票后,SQL Server 2012 存储过程都会计算视频的投票总和。

问题:

  • 少量的选票在性能方面很好。
  • 当投票达到 100,000+ 时,查询可能需要 10+ 秒才能完成(不可接受的等待时间)。

问题:

  1. 每 15-30 分钟运行一次的 SQL Server 作业是否可行?
  2. 能否将 SUM 结果“缓存”在表格列中以供 Web 应用使用?
  3. 当 Web 应用访问相同的值时,作业更新缓存的 SUM 是否存在任何问题?

【问题讨论】:

  • 那个 SPROC 除了 SUM 还做了什么吗? SUM 应该不会花很长时间。
  • 只是 SUM(实际时间有点夸张)。会有一个处理时间太长而无法等待的点(可能更像是数百万),因此需要某种缓存。另外,我不希望每个投票同时触发相同的查询,因为这肯定会影响性能。
  • 存储过程可以计算 SUM = 当前 SUM +/- 1,而不是每次聚合吗?
  • 这样计算会不会有并发问题?比如说,3票同时进来?
  • 如果总和存储在他们自己的表中,那么不会。执行该过程 3 次将导致 3 次更新。

标签: c# asp.net sql-server performance caching


【解决方案1】:

更新 100k 行的 SUM 需要 10 秒,这意味着您的表设计不佳。你缺少一个索引,或者更多。更新 100k 行的总和应该需要 10 毫秒或更短的时间。

除此之外,SQL Server 还可以为您维护 SUM。只需在所需表达式上创建索引视图。见Create Indexed Views。 SUM 是索引视图中支持的聚合。

这是SqlFiddle。

索引视图优于自制解决方案(例如,在触发器中维护的列),因为,首先,正确并且更简单(更少代码),由引擎在 任何情况并且不会漂移(例如,如果触发器暂时禁用)。即使考虑到任何基于触发器的解决方案所固有的所有缺点,这也是没有的。

【讨论】:

  • 谢谢 - 实际上并不需要那么长时间。我只是在预测数百万行的行,查询可能太慢而用户等待。您是否发现在 VIDEO 表中使用列以及存储过程同时递增/递减的任何问题(请参阅原始帖子上的 cmets)?
【解决方案2】:

回答您的问题:

  1. 我会说不。这种大小的桌子上的总和应该不是问题,你可能在其他地方有问题。一旦超过一百万行,您可能会考虑将其作为一个选项,但您还需要做一些其他事情,以确保数据不会过快变得过时。
  2. 执行计划可以,但结果不会。
  3. 是的,但您不应该注意到它。当您执行全表 SELECT 时,您将锁定表以便聚合函数可以运行,但这只会阻止写入。如果您花时间写一行并且聚合函数无法锁定表,您可能会遇到问题,但我无法想象这种类型的应用程序会如何导致明显的锁定。

您是否尝试过为该列编制索引以便服务器生成列统计信息? SUM 值(在我看来)可能是一个统计数据,因此这可能会加快速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    相关资源
    最近更新 更多