JDBC - PostgreSQL - 批量插入 + 唯一索引
JDBC - PostgreSQL - batch insert + unique index
我有一个 table 在某些字段上具有唯一约束。我需要在此 table 中插入大量记录。为了加快速度,我使用 JDBC 的批量更新(驱动程序版本为 8.3-603)。
有没有办法做到以下几点:
每个批处理我都需要写入table批处理中不违反唯一索引的所有记录;
每个批处理执行我都需要从批处理中接收未插入数据库的记录,因此我可以保存 "wrong" 条记录
?
最有效的方法是这样的:
- 创建一个与目标table具有相同结构但没有唯一约束
的暂存table
- 将所有行批量插入到该暂存区 table。最有效的方法是使用
copy
或使用 CopyManager (虽然我不知道你的旧驱动程序版本是否已经支持它。
完成后,将有效行复制到目标中 table:
insert into target_table(id, col_1, col_2)
select id, col_1, col_2
from staging_table
where not exists (select *
from target_table
where target_table.id = staging_table.id);
注意以上是不是并发安全!如果其他进程做同样的事情,您可能仍然会遇到唯一密钥违规。为了防止你需要锁定目标 table.
如果要删除复制的行,可以使用可写 CTE 来实现:
with inserted as (
insert into target_table(id, col_1, col_2)
select id, col_1, col_2
from staging_table
where not exists (select *
from target_table
where target_table.id = staging_table.id)
returning staging_table.id;
)
delete from staging_table
where id in (select id from inserted);
staging_table.id
上的(非唯一)索引应该有助于提高性能。
我有一个 table 在某些字段上具有唯一约束。我需要在此 table 中插入大量记录。为了加快速度,我使用 JDBC 的批量更新(驱动程序版本为 8.3-603)。 有没有办法做到以下几点:
每个批处理我都需要写入table批处理中不违反唯一索引的所有记录;
每个批处理执行我都需要从批处理中接收未插入数据库的记录,因此我可以保存 "wrong" 条记录
?
最有效的方法是这样的:
- 创建一个与目标table具有相同结构但没有唯一约束 的暂存table
- 将所有行批量插入到该暂存区 table。最有效的方法是使用
copy
或使用 CopyManager (虽然我不知道你的旧驱动程序版本是否已经支持它。
完成后,将有效行复制到目标中 table:
insert into target_table(id, col_1, col_2)
select id, col_1, col_2
from staging_table
where not exists (select *
from target_table
where target_table.id = staging_table.id);
注意以上是不是并发安全!如果其他进程做同样的事情,您可能仍然会遇到唯一密钥违规。为了防止你需要锁定目标 table.
如果要删除复制的行,可以使用可写 CTE 来实现:
with inserted as (
insert into target_table(id, col_1, col_2)
select id, col_1, col_2
from staging_table
where not exists (select *
from target_table
where target_table.id = staging_table.id)
returning staging_table.id;
)
delete from staging_table
where id in (select id from inserted);
staging_table.id
上的(非唯一)索引应该有助于提高性能。