MAX和Top 1哪个更好?- 哪个更适合IT技术领域?

50

我需要审查一些代码,发现有人写了这样的代码,但是想不到为什么我的方法更好,而且可能并不更好,那么哪种方法更好/更安全/更有效?

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

我本来会选择第二个选项,但是我不确定为什么选择那个选项是正确的。


2
如果a_primary_key确实是表的主键列,那么查询中提到TOP 1 .. ORDER BY或者MAX .. GROUP BY就没有意义了。主键唯一标识单个行,对于单个行来说排序或者求最大值都没有意义,只需要使用SELECT a_date FROM a_table WHERE a_primary_key = 5即可;无论如何你都会得到0到1个结果。 - Caius Jard
8个回答

49

23

如果你的表进行了索引,性能通常相似。

值得考虑的是:Top通常只有在对结果进行排序时才有意义(否则,top是关于什么的?)

对结果进行排序需要更多的处理。

最小值不总是需要排序。(只是取决于情况,但通常不需要使用order by或group by等)

在你的两个例子中,我期望速度/x-plan非常相似。你可以查看统计数据来确保,但我怀疑差异会很大。


1
SQL Server的TOP 1与使用rowNum = 1的Oracle行为不同。实际上,Oracle在排序之前确实会抓取它找到的第一个,因此此方法仅适用于SQL Server。使用TOP 1而不是Max()的另一个好处是,只要包括适用的排序,就可以获取任意数量的列。我使用Max()进行了测试,即使使用GROUP BY,它似乎也无法产生仅1条记录。也许有人可以说如何在不使用子查询的情况下从多个列中获取顶部的一行? - gordon
3
上面的“max”代码返回多个条目的原因是由于团购。它为每个事件ID返回一个最大值,因此其实与“top”示例具有不同的语义。 - MultiMat

13

这两个查询有所不同。

第一个查询返回多条记录(在内找到每个的最大a_date

第二个查询返回一条记录(在内找到最小的a_date)。


2
o.O 第一个查询仍将返回一条记录。 - Nick Rolando
2
@Shredder 如果 a_primary_key 确实是主键,那么它会生效。但如果它是一个主键,那么在 a_date 中只有一个日期,你既不需要 max 也不需要 top - GSerg
2
@Shredder,你能看到第一个查询有GROUP BY吗?还是你假设第二个查询中的ORDER BY也意味着第一个查询中也有ORDER BY - GSerg
4
@Shredder,你可能因为发布了w3schools的链接而遭受指责或嘲讽。 :) - Taryn
我的错,我在测试时使用了w3schools而不是sql fiddle。 - user2330678
显示剩余6条评论

6

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

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

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


4
在第一个示例中不需要按组分组(因为根据你的WHERE子句,你只有一个组)。 - Chains
@kuru:我不确定你能否在没有group by的情况下使用聚合函数,但如果可以的话...你是正确的。 - vol7ron
3
只要你只选择聚合值(就像你在回答中所做的那样),那么就没有问题。如果你在选择中包括非聚合值,那么就需要使用分组语句。 - Chains
谢谢您的跟进,那是我的初步想法,但我会相信您的话并更新答案,+1 干杯 - vol7ron

3

我在一张拥有20,00,000+条记录的表上执行了max和top操作,并发现Top比max或min函数更快地给出结果,尤其是在使用order by时。

因此,最好的方法是逐个执行两个查询一段时间,并检查连接经过的时间。


2

除了那些非常出色的回答指出这两个查询实际上有很大不同之外,我想指出如果没有符合选择条件的行,则结果将非常不同。

  • SELECT MAX()将返回一个带有空值的结果
  • SELECT TOP 1将返回零个结果

这些是非常不同的事情。


1

MAXTOP函数的作用不同。您的第一个查询将返回每个不同event_id找到的具有a_primary_key = 5a_date的最大值。第二个查询将仅获取结果集中找到的第一个具有a_primary_key = 5a_date


2
它不会获取第一个值。当与“order by asc”结合使用时,“Top”将选择最小值。 - GSerg
1
你到底在抽什么,兄弟?给我也来点吧。它获取找到的第一个值,并且是最小的,因为按升序排序时,从最小到最大进行排序,使第一个值为最小值。 - Nick Rolando

-1
我进行了一个实验,当我使用像Min/Max这样的聚合函数时,集群索引成本达到了98%,但是当我使用TOP和Order By时,集群索引扫描成本降低到了45%。在查询大型数据集时,TOP和Order By组合将更加经济实惠,并且能够提供更快的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接