【问题标题】:How to tell if SQL server is trimming the result if TOP is used?如果使用 TOP,如何判断 SQL 服务器是否正在修剪结果?
【发布时间】:2015-05-07 13:13:51
【问题描述】:

我有这个 SQL 查询:

SELECT TOP 10 * FROM MyTable

如何判断结果是否缩短,即 MyTable 实际上有超过 10 行?

【问题讨论】:

  • 附注我对此感兴趣的原因是,如果有更多结果,我想记录结果集被缩短的事实。如果我不添加任何限制,那么结果集可能会非常庞大​​,这意味着 SQL Server 将陷入停顿。
  • 做 TOP 11,你会看到的。
  • 查询top 11,只用10行
  • @jarlh 我想避免执行两个查询,因为这会使 SQL 服务器上的负载加倍。
  • 切勿在没有ORDER BY 的情况下使用TOP。如果您对事物没有自然顺序,则诸如“顶部”、“底部”、“第一”或“最后”之类的事物是未定义的。

标签: c# sql sql-server sql-server-2008-r2 sql-server-2012


【解决方案1】:

最简单的方法是在同一查询中添加一个 COUNT..OVER 列,该列返回表中的总行数:

SELECT TOP 10 *, COUNT(*) OVER() As TotalRows FROM MyTable

这个总数是在执行 FROM 和 WHERE 子句之后计算的,但在应用 TOP 子句之前之前

【讨论】:

  • 但是,我想我还要指出一个事实,即选择没有 order by 子句的 top x 记录是荒谬的。
  • @Zohar Peled 不,这不是荒谬的 - 它避免了对您的数据库进行大规模查询的拒绝服务攻击,如果用户无意中触发了一个返回 1 亿行的查询怎么办?必须将其限制在合理的范围内,例如32,768 行,但仅此而已。
  • @Contango 我不同意。这是荒谬的,因为不使用 order by 子句就无法保证记录的顺序。这意味着您可能无法获得预期的结果。
  • @Contango 实际上,我同意你的看法。我过去曾为网站实施过类似的事情,但权衡取舍并不常见。添加ORDER BY 使其一致,对于罕见/异常事件,但代价是对每个查询进行潜在的昂贵排序。由于在这种情况下所有客户真正需要知道的是“是否有比我得到的更多行?”,我通常不赞成在这种情况下使用 ORDER BY。
  • @Zolar Peled TOP 的目的是在紧急情况下限制结果。如果返回的结果过多,则说明出现了严重错误,其目的是限制损害,而不是让查询使 SQL Server 陷入停顿。在这种特殊情况下,添加 ORDER BY 会适得其反,因为它会减慢正常查询的速度。
【解决方案2】:

作弊:

SELECT TOP 11 * FROM MyTable

并检查是否有 11 行 :-) 然后忽略第 11 行。请注意,从您写的评论中,您可能没有理解:您执行此查询而不是 TOP 10 查询。

如果有 TOP 10 返回。如果有 11 行,那么显然 TOP 10 是不够的。

【讨论】:

    【解决方案3】:

    您可以使用COUNT 获取总行数。

    SELECT COUNT(*)
    FROM MyTable
    

    您可以检查该结果是否大于 10 以确定它是否超过 10 行。

    【讨论】:

      【解决方案4】:

      您可以使用count(*) 作为额外列返回总行数。

      类似这样的:

      select top 10 T1.*, T2.Total
      from MyTable as T1
          outer apply (select count(*) as Total from MyTable) as T2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-29
        • 1970-01-01
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多