1

我的情景:PostgreSQL的並行BULK INSERT不併行

  • 10個工作
  • 數據庫已成立100個最大連接數
  • 每個工人都有自己的數據庫連接(最多10個連接。 )
  • 每個工人開始一筆交易(BEGIN; COMMIT;)
  • 每個工人都將數據插入交易中的批量插入同一表中
  • 要插入的數據例如一個百萬行
  • 每個工人處理

每個工人的查詢1000行(尺寸1000批次):

BEGIN; 
    INSERT INTO "test_tbl" ("id",...) VALUES 
    (...),(...),...[1000 entries]... RETURNING id; 
COMMIT; 

test_tbl只與指數CREATE UNIQUE INDEX formulas_pkey ON formulas USING btree (id)

約束 PRIMARY KEY (id)

問題

經過許多小時的分析後,接線員工等待另一名工人完成插入。爲什麼工人不能同時將新數據插入同一張表中?

UPDATE

我已經刪除了所有的約束和所有索引(主鍵,外鍵等),但仍是同樣的問題。沒有並行化。

補充說明:

  • 數據到例如插入一個百萬行
  • 每個工人處理1000行(大小1000的批次)
+0

相似[SO question](http://stackoverflow.com/q/32087233/1835769)。 – displayName

回答

1

,有一個主密鑰的事實意味着該數據庫有以檢查相應的列(多個)是的值UNIQUENOT NULL。開始插入數據的第二個事務在第一個事務尚未完成插入之前無法完成(否則,可能是是非唯一值)。

如果您不想在每個工作人員的交易(但是,批量爲100個插入)下進行批量插入,則工作速度會更快。您將需要更多的客戶端和數據庫之間的電話(您將有n調用與100行數據,而不是非常大的電話與n * 100行);但數據庫將能夠早日提交。

PostgreSQL

讀不會阻塞寫,寫不會阻塞讀

...但交易1 可以(而且經常會)塊交易2 還寫

如果你不能做批量插入,你可以嘗試推遲在transaction.This結束時PRIMARY KEY約束通過定義PRIMARY KEY約束DEFERRABLE INITIALLY DEFERRED(這是不是對PostgreSQL的默認完成的,雖然它是SQL標準)。見documentation for "create table"

DEFERRABLE
NOT DEFERRABLE

該控制約束是否可以被推遲。每個命令後都會立即檢查不可延遲的約束。可以推遲檢查可推遲的約束,直到事務結束(使用SET CONSTRAINTS命令)。 NOT DEFERRABLE是默認值。目前,只有UNIQUE,PRIMARY KEY,EXCLUDE和REFERENCES(外鍵)約束才接受此子句。

+0

Thx @joanolo!請閱讀我的更新。 – phlegx

+0

你是什麼意思:「如果你只是不對每個工人進行1次交易(但是,批量爲100個插入)進行批量插入,它將工作得更快。」?我的工作人員在1筆交易中批量插入1000個條目。 – phlegx

+0

這在您的原始文章中並不清楚。所做的更改現在已經清楚了。 – joanolo