我在 PostgreSQL 13 中有一个简单的表格,如下所示:
table name: newtable1
field type
----- ----
Seq bigserial
code varchar
Seq
是主键(自增)
Code
是唯一键索引
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing --> Seq value is 1
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('002') On Conflict(Code) Do Nothing --> Seq value is 4
问题
为什么Seq值不断增加?
如果成功插入,有没有办法只增加 Seq 值?
原因是在检查重复项(尝试输入索引元组)之前
DEFAULT
应用了值(以及触发器和任何其他可能更改行值的内容)。数字旨在抵御并发负载下的竞争条件。一旦增加,底层证券就不会“收回”数字。还有其他情况会烧掉序列号。因此,序列号的差距是可以预料的。只要您不以巨大的速度销毁数字,这应该不是问题。serial
SEQUENCE
并非没有(或多或少)严重影响性能,例如使用
SERIALIZABLE
事务隔离或手动锁定策略。这就是为什么ON CONFLICT
条款(“UPSERT”)首先存在的原因。如果您实际上没有对同一个表进行并发写入(您确定吗?),则此替代查询将避免烧录序列号:
在非冲突情况下,它会稍微贵一些,因为它首先检查索引中是否存在,然后实际输入表和索引中的新行。但对于有冲突的情况,速度会稍快一些。检查和写入之间有一个很小的窗口,其中竞争条件可能会在并发写入负载下导致问题。那是我们使用UPSERT的时候。
有关的: