postgresql - "order by foo, bar"和 "order by (foo, bar)"之间的差异(带括号)

标签 postgresql

我对 Postgres 很感兴趣,但我想答案可能是普遍相同的。我很好奇这两个查询之间有什么不同(如果有的话),其中 foo 是数字(bigint),bar 是字符串(varchar),它们一起构成向上主键(foo,bar)。

select * from my_table order by foo, bar for update
select * from my_table order by (foo, bar) for update

解释计划存在差异(见下文),但如果它实际上改变了锁定顺序,这对我来说并不明显,这才是我真正感兴趣的。我正在与一些偶尔的死锁作斗争,而其中一个我注意到两种不同的排序规则之间的使用不一致。也许这就是原因?

LockRows  (cost=83.37..98.37 rows=1200 width=78)
  ->  Sort  (cost=83.37..86.37 rows=1200 width=78)
        Sort Key: (ROW(foo, bar))
        ->  Seq Scan on my_table  (cost=0.00..22.00 rows=1200 width=78)
LockRows  (cost=0.15..78.15 rows=1200 width=46)
  ->  Index Scan using my_table_pkey on my_table  (cost=0.15..66.15 rows=1200 width=46)

最佳答案

(foo, bar) 是匿名记录类型的单列(也称为 row constructor )。

由于该(单个)列没有索引,Postgres 必须读取整个表(“顺序扫描”)才能按表达式进行排序。它与 order by foo||bar 类似(但不相同)。

当选择明显属于主键索引的两列时,Postgres 可以按索引顺序查找行,从而跳过排序。

如果运行select (foo, bar) from ...,您可以看到差异,输出只有一列。

but it's not obvious to me if it actually changes the lock order

排序顺序不受影响,但性能受到影响(正如您在执行计划中看到的)


在 Postgres 中将多个列放在括号之间通常是错误的(并且在其他数据库中几乎没有用)

关于postgresql - "order by foo, bar"和 "order by (foo, bar)"之间的差异(带括号),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65336179/

相关文章:

SQL 架构设置

postgresql - 存储过程帮助获取 ID 并从另一个表中获取结果

sql - postgresql 不返回特定数字标准的值

python - 如何将 python 列表插入到 Postgres 表中

sql - 跨字段选择 MIN 和 MAX 并按用户聚合

django - 如果第二个表中存在过滤行,则注释 django 查询

java - PostgreSQL 错误 : canceling statement due to user request

ruby-on-rails - 来自 postgresql 的 Rails 自动轮毫秒查询

SQL在子查询中使用来自join的表

node.js - 如何使用在 docker 中运行的 Node 在微服务架构中初始化 postgres 数据库表