"order by foo, bar" 和 "order by (foo, bar)" 的区别(带括号)

Pat*_*ody 2 postgresql

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

select * from my_table order by foo, bar for update
Run Code Online (Sandbox Code Playgroud)
select * from my_table order by (foo, bar) for update
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)

a_h*_*ame 5

(foo, bar)是匿名记录类型的单列(也称为行构造函数)。

由于该(单个)列没有索引,Postgres 必须读取整个表(“Seq Scan”)才能按表达式进行排序。它与order by foo||bar.

选择显然是主键索引的一部分的两列,Postgres可以在索引顺序中查找行,并跳过排序。

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

但它是否真的改变了锁定顺序对我来说并不明显

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


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