【问题标题】:MAX vs Top 1 - which is better?MAX 与 Top 1 - 哪个更好?
【发布时间】:2011-08-25 23:13:40
【问题描述】:

我不得不查看一些代码,并且遇到了有人做过的事情,并且想不出为什么我的方法更好而可能不是的原因,那么,哪个更好/更安全/更有效?

SELECT MAX(a_date) FROM a_table WHERE a_primary_key = 5 GROUP BY event_id

SELECT TOP 1 a_date FROM a_table WHERE a_primary_key = 5 ORDER BY a_date

我会选择第二个选项,但我不确定为什么,以及是否正确。

【问题讨论】:

  • 如果a_primary_key 确实是表的主键列,那么查询提及TOP 1 .. ORDER BYMAX .. GROUP BY 是没有意义的。一个主键唯一标识一行;没有必要订购或最大化单行,只需说SELECT a_date FROM a_table WHERE a_primary_key = 5;无论如何,您都会得到 0 到 1 个结果

标签: sql sql-server tsql


【解决方案1】:

1) 当在要查询的表和列上有聚集索引时,MAX() 运算符和查询SELECT TOP 1 的性能几乎相同。

2) 当没有聚集索引在表和要查询的列上时,MAX() 操作符提供更好的性能。

参考:http://www.johnsansom.com/performance-comparison-of-select-top-1-verses-max/

【讨论】:

    【解决方案2】:

    如果您的表被索引,性能通常相似。

    值得考虑:Top 通常只有在您订购结果时才有意义(否则,top of what?)

    订购结果需要更多处理。

    Min 并不总是需要订购。 (只是取决于,但通常你不需要 order by 或 group by 等)

    在您的两个示例中,我希望速度/x-plan 非常相似。您可以随时查看统计数据来确定,但我怀疑差异会很大。

    【讨论】:

    • SQL Server TOP 1 的行为与使用 rowNum=1 的 Oracle 不同。 Oracle 实际上确实在排序之前获取了它找到的第一个,因此这种方法仅对 SQL Server 有效。这个 TOP 1 vs Max() 的另一个好处是,只要包含适用的排序,您就可以获取任意数量的列。我使用 Max() 进行了测试,发现即使使用 GROUP BY 似乎也没有只产生 1 条记录。如果你想在没有子查询的情况下从多列中获取顶部,也许更强大的 mojo 可以说如何只获取一行?
    • 上面的'max'代码返回多个条目的原因是因为团购。它为每个事件 ID 返回一个 MAX。所以它实际上与“顶部”示例具有不同的语义。
    【解决方案3】:

    它们是不同的查询。

    第一个返回许多记录(在 a_primary_key = 5 中找到的每个 event_id 中最大的 a_date

    第二个返回一条记录(在a_primary_key = 5 中找到的最小的a_date)。

    【讨论】:

    • o.O 第一次查询还是会返回一条记录
    • @Shredder 提供 a_primary_key 实际上是一个主键,它会。但是如果是主键,a_date中只有一个日期,既不需要max也不需要top
    • 即使不是,它仍然会返回一条记录。 w3schools.com/sql/sql_func_max.asp
    • @Shredder 你能看到第一个查询有GROUP BY,还是假设第二个查询中的ORDER BY 意味着第一个查询中也有ORDER BY
    • @Shredder 你可能会因为发布到 w3schools 的链接而被涂上焦油和羽毛。 :)
    【解决方案4】:

    要使查询具有相同的结果,您需要:

    SELECT MAX(a_date) FROM a_table WHERE a_primary_key = 5
    
    SELECT TOP 1 a_date FROM a_table WHERE a_primary_key = 5 ORDER BY a_date DESC
    

    了解哪个更快的最佳方法是检查查询计划并进行基准测试。有很多因素会影响速度,例如表/堆大小等。甚至同一数据库的不同版本也可能会被优化,以支持一个查询而不是另一个查询。

    【讨论】:

    • 在第一个示例中不需要分组(因为根据您的 WHERE 子句,您只有一个组)。
    • @kuru:我不确定你是否可以使用不带 group by 的聚合函数,但如果是这样......你是对的
    • 只要您只选择 aggs(就像您在答案中所做的那样),就可以了。如果您在选择中包含非聚合值,那么您确实需要一个分组依据。
    • 感谢您的跟进,这是我最初的想法,但我会相信您的话并更新答案,+1 欢呼
    【解决方案5】:

    我在一张有 20,00,000+ 条记录的表上执行 max 和 top , 并发现 Top 的结果比 max 或 min 函数更快

    所以,最好的方法是在一段时间内一个一个地执行你的查询,然后检查连接经过的时间。

    【讨论】:

      【解决方案6】:

      MAXTOP 的功能不同。您的第一个查询将返回为 a_date 找到的最大值,其中每个不同的 event_id 都有一个 a_primary_key = 5。第二个查询将简单地抓取第一个a_date,并在结果集中找到a_primary_key = 5

      【讨论】:

      • 它不会获取第一个值。 Toporder by asc 结合使用时,将选择最小值。
      • 你在抽烟吗兄弟,给我一些。它抓取找到的第一个值,是的,在这种情况下,它将是自 ASC 订购以来最小的值从最小到最大,使第一个值最小..
      【解决方案7】:

      要添加其他出色的响应,指出查询确实做了非常不同的事情,我想指出,如果选择中没有符合条件的行,结果将非常不同。

      • SELECT MAX() 将返回一个值为 NULL 的结果
      • SELECT TOP 1 将产生零个结果

      这些是非常不同的东西。

      【讨论】:

        【解决方案8】:

        我进行了一个实验,当我使用像 Min/Max 这样的聚合时,聚集索引成本为 98%,但是当我使用 TOP 和 Order By 时,聚集索引扫描成本降低到 45%。在查询大型数据集时,TOP 和 Order By 的组合会更便宜,并且会提供更快的结果。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-07-03
          • 2017-03-22
          • 1970-01-01
          • 2014-04-02
          • 2013-11-28
          • 2010-10-11
          • 2013-09-10
          相关资源
          最近更新 更多