cha*_*der 1 sql database postgresql crud bigdata
我有一个只有一张表的数据库。该表需要每隔几周更新一次。我们需要将第三方数据引入其中,它将包含 100-1.2 亿行。所以流程基本上是:
检测和执行更新的最佳方法是什么?一些选项是:
您认为最好的选择是什么,或者是否有其他选择?
Postgres 有一个关于提高批量加载性能的有用指南。根据您的描述,除了批量和INSERT之外,您还需要执行批量操作 。以下是提高效率的大致分步指南:UPDATEDELETE
ALTER SYSTEM SET max_wal_size = <size>;
Run Code Online (Sandbox Code Playgroud)
您还可以完全禁用 WAL。
ALTER SYSTEM SET wal_level = 'minimal';
ALTER SYSTEM SET archive_mode = 'off';
ALTER SYSTEM SET max_wal_senders = 0;
Run Code Online (Sandbox Code Playgroud)
请注意,这些更改需要重新启动数据库才能生效。
您希望所有工作都在一个事务中完成,以防出现任何问题。跨多个连接并行运行 COPY 通常不会提高性能,因为磁盘通常是限制因素。
SET LOCAL maintenance_work_mem = <size>
...
Run Code Online (Sandbox Code Playgroud)
如果您要对 Postgres 内的数据进行任何其他特殊处理(work_mem通常是最重要的,特别是使用 Postgis 扩展时),您可能需要设置其他配置参数。请参阅本指南,了解对性能最重要的配置变量。
CREATETEMPORARY没有约束的表。CREATE TEMPORARY TABLE changes(
id bigint,
data text,
) ON COMMIT DROP; --ensures this table will be dropped at end of transaction
Run Code Online (Sandbox Code Playgroud)
changes使用COPY FROM使用COPY FROM命令将原始数据批量插入到临时表中。
COPY changes(id,data) FROM ..
Run Code Online (Sandbox Code Playgroud)
DROP可能会减慢处理速度的关系target表上的DROP所有外键约束、索引和触发器(如果可能)。不要删除您的主键,因为您需要将其用于INSERT.
target向表中添加跟踪列向表中添加一列target以确定更改表中是否存在行:
ALTER TABLE target ADD COLUMN seen boolean;
Run Code Online (Sandbox Code Playgroud)
changes中target:UPSERT 是通过ON CONFLICT向标准INSERT语句添加子句来执行的。这避免了执行两个单独操作的需要。
INSERT INTO target(id,data,seen)
SELECT
id,
data,
true
FROM
changes
ON CONFLICT (id) DO UPDATE SET data = EXCLUDED.data, seen = true;
Run Code Online (Sandbox Code Playgroud)
DELETE不在changes表中的行DELETE FROM target WHERE not seen is true;
Run Code Online (Sandbox Code Playgroud)
DROP跟踪列和临时changes表DROP TABLE changes;
ALTER TABLE target DROP COLUMN seen;
Run Code Online (Sandbox Code Playgroud)
添加回已删除的所有约束、触发器和索引,以提高批量更新插入性能。
批量更新插入/删除已完成,应在事务外部执行以下命令。
VACUUM ANALYZE在桌子上运行target。这将允许查询规划器对表做出适当的推断并回收死元组占用的空间。
SET maintenance_work_mem = <size>
VACUUM ANALYZE target;
SET maintenance_work_mem = <original size>
Run Code Online (Sandbox Code Playgroud)
ALTER SYSTEM SET max_wal_size = <size>;
...
Run Code Online (Sandbox Code Playgroud)
您可能需要再次重新启动数据库才能使这些设置生效。