Postgresql:单独的 UPSERT(INSERT INTO ... ON CONFLICT)的效率与组合成单个命令的效率
Postgresql: efficiency of separate UPSERTs (INSERT INTO ... ON CONFLICT) vs combining into single command
以下哪个 UPSERT
操作更 高效 (等同于执行速度更快)?还是没有什么区别?
单独查询:
INSERT INTO mytable (col_1, col_2) VALUES (312, 42) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
INSERT INTO mytable (col_1, col_2) VALUES (933, 32) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
...
INSERT INTO mytable (col_1, col_2) VALUES (121, 16) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
或者将相同的命令组合成一个查询:
INSERT INTO mytable (col_1, col_2) VALUES
(312, 42) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2
(933, 32) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2
...
(121, 16) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
请记住,我说的是要完成 很多 个 INSERT
命令...分批(很多)每批大约 750000 INSERT
个命令。
在你的情况下,第一个变体是唯一安全的。
在使用 ON CONFLICT
子句时,在单个查询中插入多条记录是不安全的,如果插入的两行具有相同的冲突键值,则可能会出现 "ON CONFLICT can not affect the same row twice."
之类的致命错误。
正如评论中@a_horse_with_no_name所说,运行单个语句通常比多个语句更有效。但是,正确的语法是
INSERT INTO mytable (col_1, col_2)
VALUES
(312, 42),
(933, 32),
...
(121, 16)
ON CONFLICT col_1 DO UPDATE
SET col_2 = excluded.col_2;
请注意,当您使用参数化查询执行此操作时,参数数量有限制,因此您可能必须对它们进行批处理。
以下哪个 UPSERT
操作更 高效 (等同于执行速度更快)?还是没有什么区别?
单独查询:
INSERT INTO mytable (col_1, col_2) VALUES (312, 42) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
INSERT INTO mytable (col_1, col_2) VALUES (933, 32) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
...
INSERT INTO mytable (col_1, col_2) VALUES (121, 16) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
或者将相同的命令组合成一个查询:
INSERT INTO mytable (col_1, col_2) VALUES
(312, 42) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2
(933, 32) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2
...
(121, 16) ON CONFLICT col_1 DO UPDATE SET col_2=excluded.col_2;
请记住,我说的是要完成 很多 个 INSERT
命令...分批(很多)每批大约 750000 INSERT
个命令。
在你的情况下,第一个变体是唯一安全的。
在使用 ON CONFLICT
子句时,在单个查询中插入多条记录是不安全的,如果插入的两行具有相同的冲突键值,则可能会出现 "ON CONFLICT can not affect the same row twice."
之类的致命错误。
正如评论中@a_horse_with_no_name所说,运行单个语句通常比多个语句更有效。但是,正确的语法是
INSERT INTO mytable (col_1, col_2)
VALUES
(312, 42),
(933, 32),
...
(121, 16)
ON CONFLICT col_1 DO UPDATE
SET col_2 = excluded.col_2;
请注意,当您使用参数化查询执行此操作时,参数数量有限制,因此您可能必须对它们进行批处理。