我对 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/