小编典典

大于或等于ALL()且等于MAX()速度

sql

我在PostgreSQL中有一个名为的关系,该关系product包含2个字段:idquantity,我想找到id具有最高值的产品quantity。据我所知,有两种方法可以做到:

SELECT id FROM product WHERE quantity >= ALL(SELECT quantity FROM product)

或者

SELECT id FROM product WHERE quantity = (SELECT MAX(quantity) FROM product)

他们的执行速度有什么不同吗?


阅读 269

收藏
2021-03-10

共1个答案

小编典典

如果有任何行,第一个查询将失败quantity IS NULL(如Gordon所示)。
仅当所有行都具有时,第二个查询才会失败quantity IS NULL。因此,它在大多数情况下应该是可用的。(而且速度更快。)

如果在 Postgres 12或更早版本中 需要NULL安全查询,即NULL是有效结果,请考虑:

SELECT id, quantity
FROM   product
WHERE  quantity IS NOT DISTINCT FROM (SELECT MAX(quantity) FROM product);

或者,可能更快:

SELECT id, quantity
FROM  (
   SELECT *, rank() OVER (ORDER BY quantity DESC NULLS LAST) AS rnk
   FROM   product
   ) sub
WHERE  rnk = 1;

看:

Postgres 13 添加了标准的SQL子句 WITH TIES

SELECT id
FROM   product
ORDER  BY quantity DESC NULLS LAST
FETCH  FIRST 1 ROWS WITH TIES;

db
<>在这里拨弄

可使用任何数量的NULL值。

手册:

SQL:2008引入了不同的语法来实现相同的结果,PostgreSQL也支持该语法。它是:

OFFSET start { ROW | ROWS }
FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }

在这种语法中,标准要求 _ start or _ count
值是文字常量,参数或变量名;作为PostgreSQL扩展,允许使用其他表达式,但通常需要将其括在括号中以避免歧义。如果 _ count_
FETCH子句中省略if ,则默认为1。此WITH TIES 选项用于根据该ORDER BY子句返回与结果集中最后一行相关的所有其他行;否则,默认为1 。ORDER BY在这种情况下是强制性的。ROWROWS以及FIRSTNEXT是不影响这些条款的影响干扰词。

值得注意的是,WITH TIES不能与(non-standard)short语法一起使用LIMIT n

这是 最快的解决方案 。比您当前的任何一个查询都要快。对于 性能而言 更重要:在上有一个
索引(quantity)。或更专业的覆盖索引允许仅索引扫描(速度稍快一点):

CREATE INDEX ON product (quantity DESC NULLS LAST) INCLUDE (id);

看:

我们需要NULLS LAST使NULL值最后以降序排列。看:

2021-03-10