【问题标题】:'Bypass' execution on huge resultset在巨大的结果集上“绕过”执行
【发布时间】:2015-02-12 16:11:25
【问题描述】:

我们最近更新了应用程序中基于网络的报告,以允许用户使用广泛的搜索条件搜索数据,例如显示所有参加过的培训课程,可以追溯到 1990 年

虽然客户对此感到满意,但有时(对于一个非常大的客户),SQL Server 可以返回巨大的结果集,例如900,000 行。从 SQL 检索并传递到 ASP.Net 可能需要五分钟以上的时间。

虽然我希望能够在报告工具中提供灵活性,但我需要将结果集限制为可由用户/浏览器管理,并尽量减少 SQL 被“锁定”以执行此操作的时间。

技术栈如下:

ASP.Net 4.5 web forms <> Data Access Layer <> SQL Procs <> SQL 2012 Standard

过程中的逻辑通常是:

  1. 对表变量执行第一次 SELECT(使用所需参数从索引表(这是一直占用的位))
  2. 对于每个附加参数,从表变量中过滤数据
  3. 返回所有行,或者如果用户已请求分组,则返回分组数据。在分组逻辑路径(例如按站点/按国家/地区)中,还会执行额外的 SELECT 以提取额外的数据

谁能建议他们在自己的工作中如何管理这个问题? SSRS 已因成本问题被驳回。到目前为止,我已经尝试了以下想法,并欢迎任何反馈:

  1. 在应用程序级别设置最大行数限制(10,000 行)
  2. 在每个过程中,设置SELECT TOP (@n) 的值,@n 为 10,001 行。在某些情况下,这会使 SQL 停止运行 5 分钟
  3. ASP.Net 检查结果集的行数,如果是&gt; 10,000,则丢弃结果集并提供友好的错误消息

这种方法效果很好,无论用户的搜索条件如何,都会强制在大约 5 秒或更短的时间内返回 10,000 条记录。但是,尽管可能有更好的方法,但我仍然存在的基本问题是:

  • 用户可以请求分组结果,因此可能只能得到 2 行数据,在所有 900,000 行分组的情况下,这需要 5 分钟才能提供。因此绕过了这个 DAL 检查
  • 初始 SELECT 上的TOP (@n) 会使分组结果不准确

我想知道是否应该抛出异常,但感觉不对。

【问题讨论】:

  • 尝试“设置行数”看看是否有帮助。 msdn.microsoft.com/en-us/library/ms188774.aspx
  • MSDN 说 “使用 SET ROWCOUNT 不会影响 SQL Server 未来版本中的 DELETE、INSERT 和 UPDATE 语句”,所以我避免了它。无论如何,结果与 TOP(N) 相同。谢谢

标签: asp.net sql-server tsql sql-server-2012 asp.net-4.5


【解决方案1】:

在您的 SP 中拆分两条路径或有两个 SP,以便在请求 Group By 选项时在初始选择表变量期间完成 Group By 操作。如果您在临时表中进行多项选择,您仍然必须在最后进行 Group By,但此初始选择将提前进行大量分组。您应该在表变量中的每个初始选择上应用 TOP 操作。对于当前情况下的所有查询,您可能只想将 10,000 放在所有查询上。大警告,您应该尝试在每个 TOP(n) 选择上放置 ORDER BY 。您会注意到性能下降,因为您现在正在执行确定性查询。您可能需要这种确定性效果,而不是更快的随机 Top(n) 记录。

简而言之,在您点击表变量之前尝试限制初始 SELECT。

在应用程序级别,如果我正在驱动一个交互式应用程序页面,那么如果超过 10,000 个解决方案,我会完全同意你的放弃。

【讨论】:

  • 谢谢。我最初无法进行分组,因为运行附加查询以将特定的附加数据拉入分组结果集中,这特定于每个分组选项并在各自的逻辑分支中执行(例如按人/按站点/按国家等)。问题是,即使我尽早应用 Top(N),分组结果也会出现偏差。如果在初始查询中返回 10,001+ 行,我几乎需要放弃查询。我认为用户在缩小搜索条件并再次运行时不会遇到问题
  • 代替 Top 尝试“设置行数”,它将在一定数量后停止处理记录。这可能会导致您对记录进行分组而不会使结果出现偏差。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 2023-01-26
  • 2011-09-10
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
相关资源
最近更新 更多