簡體   English   中英

在 Postgresql 數據庫中更新約 1 億行的最有效方法?

[英]Most efficient way of updating ~100 million rows in Postgresql database?

我有一個帶有單個表的數據庫。 該表需要每隔幾周更新一次。 我們需要將第三方數據引入其中,它將包含 100-1.2 億行。 所以流程基本上是:

  1. 從源中獲取原始數據
  2. 檢測插入、更新和刪除
  3. 進行更新並攝取到數據庫中

檢測和執行更新的最佳方式是什么? 一些選項是:

  1. 將傳入數據與當前數據庫一一比較並進行單次更新。 這似乎很慢而且不可行。
  2. 將傳入數據提取到新表中,然后用新表切換舊表
  3. 在當前表中就地批量更新。 不知道該怎么做。

你建議什么是最好的選擇,或者如果有不同的選擇?

Postgres 有一個有助於提高批量加載性能的指南。 根據您的描述,除了批量UPDATEDELETE之外,您還需要執行批量INSERT 以下是提高效率的大致分步指南:

操作前配置全局數據庫配置變量

ALTER SYSTEM SET max_wal_size = <size>;

您還可以完全禁用 WAL。

ALTER SYSTEM SET wal_level = 'minimal';
ALTER SYSTEM SET archive_mode = 'off';
ALTER SYSTEM SET max_wal_senders = 0;

請注意,這些更改需要重新啟動數據庫才能生效。

開始交易

您希望所有工作都在一個事務中完成,以防出現任何問題。 跨多個連接並行運行 COPY 通常不會提高性能,因為磁盤通常是限制因素。

在事務級別優化其他配置變量

SET LOCAL maintenance_work_mem = <size>
...

如果您在 Postgres 中對數據進行任何額外的特殊處理,您可能需要設置其他配置參數( work_mem通常在那里最重要,尤其是在使用 Postgis 擴展時。)請參閱 本指南以了解最重要的性能配置變量。

CREATE一個沒有約束的TEMPORARY表。

CREATE TEMPORARY TABLE changes(
  id bigint,
  data text,
) ON COMMIT DROP; --ensures this table will be dropped at end of transaction

使用COPY FROM批量插入changes

使用COPY FROM命令將原始數據批量插入到臨時表中。

COPY changes(id,data) FROM .. 

可以減慢處理DROP關系

target表上, DROP所有外鍵約束、索引和觸發器(如果可能)。 不要丟棄您的 PRIMARY KEY,因為您會希望它用於INSERT

將跟蹤列添加到target

target表添加一列以確定更改表中是否存在行:

ALTER TABLE target ADD COLUMN seen boolean;

UPSERT 從changes表到target表:

通過將ON CONFLICT子句添加到標准INSERT語句來執行 UPSERT。 這避免了執行兩個單獨操作的需要。

INSERT INTO target(id,data,seen) 
  SELECT 
    id,
    data,
    true
  FROM
    changes
  ON CONFLICT (id) DO UPDATE SET data = EXCLUDED.data, seen = true;

DELETE不在changes表中的行

DELETE FROM target WHERE not seen is true;

DROP跟蹤列和臨時changes

DROP TABLE changes;
ALTER TABLE target DROP COLUMN seen;

加回您為性能而放棄的關系

重新添加所有已刪除的約束、觸發器和索引以提高批量 upsert 性能。

提交事務

批量更新/刪除已完成,應在事務之外執行以下命令。

target表上運行VACUUM ANALYZE

這將允許查詢規划器對表進行適當的推斷並回收死元組占用的空間。

SET maintenance_work_mem = <size>
VACUUM ANALYZE target;
SET maintenance_work_mem = <original size>

恢復數據庫配置變量的原始值

ALTER SYSTEM SET max_wal_size = <size>;
...

您可能需要再次重新啟動數據庫才能使這些設置生效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM