在巨大的结果集上“绕过”执行

时间:2015-02-12 16:11:25

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

我们最近在我们的应用程序中更新了基于Web的报告,以允许用户使用广泛的搜索条件搜索数据,例如: 向我展示所有参加的培训课程,可以追溯到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. 中的数据
  4. 返回所有行,或者如果用户请求分组,则返回分组数据。在分组的逻辑路径中(例如,按站点/按国家/地区),还执行附加的SELECT以引入附加数据
  5. 有人可以建议他们如何在自己的工作中管理这个吗? SSRS因成本而被驳回。到目前为止,我已经尝试了以下想法,并欢迎任何反馈:

    1. 在应用程序级别设置最大行限制(10,000行)
    2. 在每个过程中,将SELECT TOP (@n)@n的值设置为10,001行。这会在某些情况下停止SQL搅拌五分钟
    3. ASP.Net检查结果集行计数,如果> 10,000,则丢弃结果集并提供友好的错误消息
    4. 这很有效,无论用户的搜索条件如何,都会强制在大约五秒或更短的时间内返回10,000条记录。然而,虽然可能有更好的方法,但我仍然存在的基本问题是:

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

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

1 个答案:

答案 0 :(得分:1)

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

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

在应用程序级别,如果我驾驶交互式应用程序页面,如果超过10,000个解决方案,我将完全放弃您的丢弃。

相关问题