create table a (
b text not null unique,
c text not null
);
-- Sleeps for 1 second as expected.
insert into a (b, c) values ('d', pg_sleep(1));
-- Sleeps for 1 second even though record is not inserted.
insert into a (b, c) values ('d', pg_sleep(1));
无论如何,是否要重构第二个语句,以便pg_sleep
仅在没有违反基于的约束时才运行(或我调用的实际密集函数)b
?请注意,c
(函数调用的结果)与约束无关。
夫妻解决方法:
insert
如果发生且没有错误,则仅使用b
和update
c
在下一条语句中。insert
缺点是我必须放松/删除not null
的约束c
,因为它将暂时为空。在咨询锁下,检查是否已存在
a
相同的b
,如果不存在,则执行insert
. 缺点是我手动复制唯一性检查,并对性能产生负面影响。
如果将检查放在同一个查询中,则仅当没有冲突行时才会执行昂贵的函数调用:
现在,在并发写入负载下插入仍然可能失败。Postgres 不允许锁定假设的行。(所以我不知道咨询锁会有什么帮助。)但只有当并发事务碰巧同时插入相同的值时才会发生这种情况,
b
并且这种情况应该非常罕见。在这种情况下,您只会失去性能优化,而不会造成任何影响。