我有一個表在某些字段上具有唯一約束。我需要在此表中插入大量記錄。爲了讓它更快,我使用JDBC進行批量更新(驅動程序版本爲8.3-603)。 有沒有辦法做到以下幾點:JDBC - PostgreSQL - 批量插入+唯一索引
每批執行我需要編寫到表中所有這一切不違反唯一索引批記錄;
每批執行我需要得到從沒有插入DB批的記錄,所以我可以拯救「錯誤」的記錄
?
我有一個表在某些字段上具有唯一約束。我需要在此表中插入大量記錄。爲了讓它更快,我使用JDBC進行批量更新(驅動程序版本爲8.3-603)。 有沒有辦法做到以下幾點:JDBC - PostgreSQL - 批量插入+唯一索引
每批執行我需要編寫到表中所有這一切不違反唯一索引批記錄;
每批執行我需要得到從沒有插入DB批的記錄,所以我可以拯救「錯誤」的記錄
?
這樣做會是這樣的最有效的方法:
copy
或使用CopyManager(雖然我不知道這是否已經在你的古老的驅動程序版本不支持一旦做到這一點,你複製的有效行到目標表:
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);
注意的是,以上不併發安全!如果其他進程做同樣的事情,你可能仍然得到唯一鍵衝突。爲了防止這種情況,你需要鎖定目標表。
如果要刪除複製行,你能做到這一點使用可寫CTE:在staging_table.id
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);
A(非唯一的)指標應該幫助的性能。
謝謝,看起來不錯。這種方式有多快?慢得多,只是批量直接插入目標表? –
不,這是不可能的。您需要先將行寫入中間表(不帶constraitns),然後使用SQL將有效的行復制到目標表中。順便說一句:你爲什麼使用這樣一個過時的驅動程序版本? –
我想使用較新的版本,但這不是我的決定:( 我怎樣才能使用中間表更高效?逐行復制並刪除複製,然後在完成時讀取該表中剩下的記錄? –
查看「bulk upsert」 –