我在这里看过很多类似的问题。但我的问题,我猜,具体。
这是我在Postgres的当前版本(9.4)中找到的最佳解决方案: http://www.depesz.com/2012/06/10/why-is-upsert-so-complicated/ http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
通常,建议的解决方案基于算法:插入一行,如果发生错误 - 执行某些操作,如果没有 - 插入下一个。
如果我只需要忽略重复错误,我可以这样做吗?
INSERT INTO tablename (id,name,surname) values (1,'john','doe')
INSERT INTO tablename (id,name,surname) values (2,'jane','smith')
而不是:
INSERT INTO tablename (id,name,surname) values (1,'john','doe'),(2,'jane','smith')
...如果我必须一次只插入约5-30行? 因此,一些插入的行只返回重复的错误,但其余的将成功执行。实际上,这就是我所需要的一切。
我试图将这些方法的成本一次与EXPLAIN INSERT
100行和100行分别进行比较。也许,我做错了,因为当我插入行单独时,它显示的执行时间缩短了约25-50倍,如第一个例子所示:
INSERT INTO tablename (id,name,surname) values (1,'john','doe')
INSERT INTO tablename (id,name,surname) values (2,'jane','smith')
这是我正在使用的查询包装器:
BEGIN;
EXPLAIN ANALYZE
-- query or queriES here
ROLLBACK;
所以,问题是,为什么我收到这个?可能是,EXPLAIN
显示每行而不是整个查询的执行时间?然后它是有道理的:在这种情况下,批量插入将比分离的命令小约3倍。正确?
答案 0 :(得分:1)
with i (id, name, surname) as (values (1,'john','doe'),(2,'jane','smith'))
insert into t (id, name, surname)
select id, name, surname
from i
where not exists (
select 1
from t
where id = i.id and name = i.name and surname = i.surname
)
如果可以以任何其他方式插入数据,则存在上述竞争条件。如果发生错误,请重试。