【问题标题】:Postgres: best solution to ignore errors during bulk insertPostgres:在批量插入期间忽略错误的最佳解决方案
【发布时间】:2015-12-28 15:46:25
【问题描述】:

我在这里看到了很多类似的问题。但我想,我的问题是具体的。

这是我为当前版本的 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 倍。对吧?

【问题讨论】:

  • 如果您选择 not 来进行批量插入,您的业务逻辑是否准备好处理其中一半的记录已插入但另一半未插入的情况?
  • 绝对!如果它不会使查询执行时间延长 50 倍,那么单独插入正是我所需要的
  • 所以您是说单独插入 100 次与批量插入 100 次相比,执行时间减少了 25-50 倍?
  • 我认为,我的结果是错误的,因为它不合逻辑。你能自己试试这个吗?不会超过几分钟
  • 我无法解释您的 EXPLAIN 结果,但无论如何您可能都不想进行单独的插入,q.v. this Stack Exchange DBA article.

标签: sql postgresql


【解决方案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
)

如果可以以任何其他方式插入数据,则存在上述竞争条件。如果发生错误,请重试。

【讨论】:

  • 您建议在每次插入时再进行两次选择。我几乎可以肯定这比没有选择的插入要花费更多)
  • @stkvtflw:“每次插入还有两个选择”:你错了,上面的查询实际上是一个语句,并且可能是最有效的。 (顺便说一句:只插入几行时不需要关心效率)
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2018-03-24
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多