我正在尝试MERGE
使用 pl/pgsql 来模拟行为:
-- Generate the data from funtion
CREATE TEMP TABLE temp_x (id int, id2 int, data text, created_at timestamp, updated_at timestamp) ON COMMIT DROP;
INSERT INTO temp_x SELECT * FROM set_gernating_function(p);
-- DELETE record with same id2
DELETE FROM x WHERE NOT EXISTS (SELECT 1 FROM temp_x WHERE temp_x.id=x.id) AND id2=p.id2;
-- UPSERT by (id, id2)
INSERT INTO x
SELECT * FROM temp_x z
ON CONFLICT(id, id2) DO UPDATE
SET
updated_at=excluded.updated_at,
data=excluded.data;
但是临时表的使用会非常pg_class
快地产生膨胀和pg_attr
表——然后我可以更快地做真空——并影响其他查询。任何想法?
有一些限制:
created_at
如果 id 已经存在,则保留时间- x 有一个删除触发器,所以没有不必要的删除。
- 速度
set_generating_function
很慢 - temp_x 的大小很小。(< 50)
- 运行速度非常高(每秒千次)