Postgresql
為 Postgres 表中的每個使用者創建一行
我在一個表中有一堆使用者行
users
,例如:| id | name | |----|-------| | 1 | Chris | | 2 | Max | | 3 | Steve |
對於這些使用者中的每一個,我想在另一個名為的表中創建一行
user_flags
:| user_id | flag | |---------|--------| | 1 | myflag | | 2 | myflag | | 3 | myflag |
目前我正在做的是一次分批下載約 100 個使用者,然後
INSERT
對每批進行批量查詢。但是我認為應該有一個更快的方法。目標:
- 盡快插入標誌行
- 長時間執行的查詢很好,只要在任何地方都沒有表鎖定
- 這些是實時查詢,因此不能刪除索引
- 應該能夠輕鬆地執行數百萬使用者行
這可能嗎?我覺得它可能/應該有一些智能功能。
這看起來相當簡單:
INSERT INTO user_flags (user_id, flag) SELECT u.id, 'myflag' -- or whatever to write to this field FROM users u LEFT JOIN user_flags uf ON uf.user_id = u.id WHERE uf.user_id IS NULL; -- to exclude already existing
如何 ..
雖然這很容易受到並發事務的競爭條件的影響,但這應該不是問題,因為您一次不會
INSERT
在多個事務中執行它。您可以將操作限制為每次呼叫n
LIMIT
行,例如 100000,只需 append ,可能與ORDER BY
:... ORDER BY u.id LIMIT 100000;
重複查詢,直到找到 < 100000 行,在單獨的事務中釋放鎖。通常,即使有數百萬行,您也會在一個命令中完成所有操作。
我建議
FOREIGN KEY
強制執行參照完整性的約束——如果你還沒有的話。ALTER TABLE user_flags ADD CONSTRAINT user_flags_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE;
以及使 1:1 關係完整的
UNIQUE
或PRIMARY KEY
約束。user_flags.user_id