【发布时间】:2012-11-09 14:12:25
【问题描述】:
我想向表中插入一条记录,如果该记录已经存在,则获取其 id,否则运行插入并获取新记录的 id。
我将插入数百万条记录,但不知道如何以有效的方式执行此操作。我现在正在做的是运行一个选择来检查记录是否已经存在,如果没有,插入它并获取插入记录的 id。随着桌子越来越大,我想SELECT 会杀了我。
我现在用 psycopg2 在 python 中做的事情看起来像这样:
select = ("SELECT id FROM ... WHERE ...", [...])
cur.execute(*select)
if not cur.rowcount:
insert = ("INSERT INTO ... VALUES ... RETURNING id", [...])
cur.execute(*insert)
rid = cur.fetchone()[0]
是否有可能在这样的存储过程中做一些事情:
BEGIN
EXECUTE sql_insert;
RETURN id;
EXCEPTION WHEN unique_violation THEN
-- return id of already existing record
-- from the exception info ?
END;
对如何优化这样的案例有任何想法吗?
【问题讨论】:
-
您似乎正在尝试实施 upsert。见depesz.com/2012/06/10/why-is-upsert-so-complicated
-
我不相信这是一个 upsert。我没有做任何更新。我有数百万条重复记录,如果它已经在数据库中,我需要记录的 ID。
-
对于一些背景:我有一个大约 40 条轧机记录值的笛卡尔积,我想将其分成 3 个表。分裂会导致很多重复。当我插入时,我将删除所有重复项。但我仍然想将 3 个表的原始连接保留在第 4 个表中。连接将在 3 个表中的记录 ID 上。
-
我的错误,这不是一个 upsert。不过,它也有类似的问题。
标签: sql performance postgresql concurrency sql-insert