最小值/最大值与 ORDER BY 和 LIMIT

MIN/MAX vs ORDER BY and LIMIT

提问人:nickf 提问时间:1/9/2009 更新时间:10/13/2021 访问量:75436

问:

在以下查询中,您认为哪种方法更好?你的原因是什么(代码效率、更好的可维护性、更少的 WTFery)......

SELECT MIN(`field`)
FROM `tbl`;

SELECT `field`
FROM `tbl`
ORDER BY `field`
LIMIT 1;
sql mysql

评论


答:

16赞 Otávio Décio 1/9/2009 #1
SELECT MIN(`field`)
FROM `tbl`;

仅仅因为它与 ANSI 兼容。限制 1 特定于 MySql,因为 TOP 特定于 SQL Server。

评论

0赞 finnw 1/9/2009
大多数 DBMS 都有限制/偏移量或等效值,并且它用于我处理过的大多数应用程序中(不是作为 MIN 的替代品,而是用于其他目的,例如分页。
0赞 Otávio Décio 1/9/2009
@finnw - 我同意,但提问者的例子是明确地将极限与最小值进行比较。
4赞 Charles Bretana 1/9/2009 #2

如果性能可以接受,我会使用第一个,因为它在语义上更接近意图。
如果性能是一个问题,(大多数现代优化器可能会将两者优化为相同的查询计划,尽管您必须进行测试以验证这一点),那么我当然会使用更快的。

5赞 mson 1/9/2009 #3

我认为答案取决于你在做什么。

如果您有一个 1 关闭查询,并且意向与您指定的一样简单,则最好选择 min(field)。

但是,通常会将这些类型的需求更改为 - 获取前 n 个结果、获取第 n 个 - 第 m 个结果等。

我不认为提交到您选择的数据库是一个太可怕的主意。更改 dbs 不应该轻易做出,必须修改是您在进行此举时付出的代价。

为什么要现在限制自己,因为你以后可能会或可能不会感到疼痛?

我确实认为尽可能多地保持 ANSI 是件好事,但这只是一个指导方针......

155赞 Sean McSomething 1/9/2009 #4

在最坏的情况下,当您查看未编制索引的字段时,使用 需要对表进行一次完整传递。使用 和 需要文件排序。如果针对大型表运行,则感知性能可能会有显著差异。作为一个轶事数据点,在我的开发服务器上,对 106,000 行表进行了 .36 秒和 84 秒。MIN()SORTLIMITMIN()SORTLIMIT

但是,如果您正在查看索引列,则更难注意到差异(在这两种情况下,无意义的数据点都是 0.00 秒)。然而,从 explain 的输出来看,它似乎能够简单地从索引中提取最小值(“选择优化的表”和“NULL”行),而 and 仍然需要对索引进行有序遍历(106,000 行)。实际的性能影响可能可以忽略不计。MIN()SORTLIMIT

这似乎是要走的路 - 它在最坏的情况下更快,在最好的情况下无法区分,是标准的 SQL,并且最清楚地表达了您想要获得的价值。正如 mson 所提到的,唯一似乎使用 和 是可取的情况是,您正在编写一个常规操作,该操作从任意列中查找顶部或底部的 N 个值,并且不值得写出特殊情况操作。MIN()SORTLIMIT

评论

13赞 Abhishek Iyer 4/26/2013
o(n) 表示单次传递,而 0(nlogn) 表示排序
1赞 dmikam 2/17/2015
@AbhishekIyer你是完全正确的,但我会添加“在最坏的情况下,对于未索引的字段”。
0赞 Robo Robok 9/22/2019
关于最糟糕的未索引情况的那部分是错误的。您总是需要进行全面扫描,否则您怎么知道它是最小值或最大值?这不像你在扫描,价值尖叫:“嘿,你终于找到我了!我是杰克,最大!
0赞 Antonio Cañas Vargas 5/30/2020
在具有 4.7 亿行的索引表的测试中,两个查询都需要 0.00 秒。但是,如果我们在查询中添加过滤器“WHERE field2=x”,则使用 LIMIT 的查询仍需要 0.00 秒,而使用 MIN 的查询仍需要 0.21 秒。
0赞 MrMesees 8/23/2021
这取决于您的表和数据库设置。我们只是通过从 with 到 with 将具有 >10M 行的数据库从多秒减少到亚秒。逻辑应该很容易理解。撇开迭代不谈,您要么需要检索 n 行,要么需要检索 1 行。order bylimitgroup bymax
12赞 user650654 10/17/2013 #5

正如 msonSean McSomething 所指出的,MIN 是可取的。

ORDER BY + LIMIT 有用的另一个原因是,如果要获取与 MIN 列不同的列的值。

例:

SELECT some_other_field, field
FROM tbl
ORDER BY field
LIMIT 1

评论

2赞 Sourav Kannantha B 5/7/2021
在这种情况下,这是否更可取?还是使用具有 max/min 的嵌套查询?(SELECT some_other_field, field FROM tbl WHERE field = ( SELECT MIN(field) FROM tbl ))
0赞 Ivan Vinitskyi 3/29/2021 #6

user650654 表示,当需要“获取与 MIN 列不同的列的值”时,LIMIT 为 1 的 ORDER BY 很有用。我认为,在这种情况下,我们仍然有更好的性能,使用 MIN 而不是排序进行两次单次传递(希望这:(优化)

SELECT some_other_field, field
FROM tbl
WHERE field=(SELECT MIN(field) FROM tbl)

评论

0赞 Charles Bretana 9/8/2022
问题本身假设 [字段] 是唯一的......否则,可能存在多个具有相同字段值的记录,而some_other_field值不同。查询将返回多行。在这种情况下,您可能希望使用其他条件将输出限制为其中一行。
1赞 Ivan Vinitskyi 9/10/2022
哦,好的。可以另外添加“限制 1”。😉