'Bypass' 在巨大的结果集上执行

'Bypass' execution on huge resultset

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

虽然客户对此很满意,但有时(对于一个非常大的客户),SQL 服务器可以 return 巨大的结果集,例如900,000 行。这可能需要五分钟以上才能从 SQL 检索并传递给 ASP.Net.

虽然我希望能够在报告工具中提供灵活性,但我需要将结果集限制为可由 user/browser 管理,并最大限度地减少 SQL 的时间 [=56] =] 开始这样做。

技术栈如下:

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

过程中的逻辑通常是:

  1. 首先将SELECT执行到一个table变量中(从索引-tables使用所需的参数(这是一直占用的位))
  2. 对于每个附加参数,过滤来自 table 变量的数据
  3. Return 所有行,或者如果用户请求分组,return 分组数据。在分组逻辑路径中(例如按 site/by 国家/地区)还执行额外的 SELECTs 以提取额外的数据

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

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

这很有效,并强制 return 在大约五秒或更短的时间内编辑 10,000 条记录,而不管用户的搜索条件如何。然而,虽然可能有更好的方法,但我仍然存在的基本问题是:

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

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

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

在应用程序级别,如果我正在驱动一个交互式应用程序页面,我将完全接受您丢弃的所有解决方案(如果超过 10,000 个解决方案)。