我的服务收到了几千个原始记录的批处理,其中每个记录都包含一个名称。预计许多记录都具有相同的名称,因此建立了以下重复数据删除策略。
records
表基本上包含每个原始记录的所有数据,但名称被指向全局names
表的ID代替,其中name
列是唯一的。
我正在使用以下查询ETL。对于每批5k记录,我在此查询后使用5k语句创建一个事务:
WITH new_id AS (
INSERT INTO names
VALUES (
DEFAULT,
@raw_name
)
ON CONFLICT (name)
DO UPDATE
SET id = (
SELECT id FROM names WHERE name = @raw_name
)
RETURNING id
)
INSERT INTO records VALUES (
DEFAULT,
(SELECT id FROM new_id),
-- other (constant) stuff
);
此处的目标是将名称插入names
表中(如果尚不存在)。在这两种情况下,都将检索名称id并将其附加到插入records
表中的记录。
执行事务大约需要2.5秒才能处理5000条记录,我正在寻找优化此查询的运行时间的方法。临时内存或表分配是可以接受的。我还可以影响批量大小(至少1k)。我必须使用现有的架构(两个表)。
(我还想知道是否有一种方法可以通过并发来对此进行优化。我可以一次触发许多ETL作业-但目前的查询将立即死锁。)
答案 0 :(得分:1)
您的性能问题可能是由于您要遍历5000多个插入命令。这是一种非常编程的工作方式,PostgreSQL引擎无法对其进行优化。
您应该尝试一种更具说明性的方法,在该方法中,您可以操作行集而不是逐行操作。这种方法应该允许PostgreSQL做更有效的工作:
MIMEBase