如何在 VALUES 和 SELECT 之间选择 INSERT?

Léo*_* 준영 6 postgresql trigger performance select postgresql-performance

这个答案向我提出了如何在这样的函数之间VALUESSELECT中进行选择的问题。在 x86_64-unknown-linux-gnu 上使用PostgreSQL 9.4.3,由 gcc (Debian 4.9.2-10) 4.9.2, 64-bit 编译

CREATE OR REPLACE FUNCTION insaft_function()
   RETURNS TRIGGER AS
$func$
BEGIN     
   INSERT INTO file_headers (measurement_id, file_header_index_start
                                           , file_header_index_end)
   VALUES (NEW.measurement_id, TG_ARGV[0]::int, TG_ARGV[1]::int);

   RETURN NULL;  -- result ignored since this is an AFTER trigger
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

VALUES处理多行,但SELECT你可以做更多的事情。这里唯一的要求是对INSERT表格执行上述操作。您可以假设INSERT在系统的持续质量保证中每个周期完成100k 次这样的操作。

我注意到这些差异与我的数据不同,这里选择了三个中值:

VALUES
real      user      sys
-------------------------------
0m0.353s  0m0.256s  0m0.028s
0m0.327s  0m0.252s  0m0.036s
0m0.358s  0m0.252s  0m0.040s
so average real 0.34s

SELECT
real      user      sys
-------------------------------
0m0.362s  0m0.256s  0m0.024s
0m0.383s  0m0.236s  0m0.056s
0m0.356s  0m0.264s  0m0.032s
so average real 0.36s
Run Code Online (Sandbox Code Playgroud)

所以这个小数据子集表明,VALUES使用如此简单的INSERT. 我对并发进程和实时数据分析的需求感兴趣。

你如何在SELECTVALUESfor之间做出决定INSERT

Erw*_*ter 6

测得的差异几乎肯定是噪声。运行更多的迭代,你不会得到一致的结果。性能差异(如果存在)将无法衡量。

您可以在此处使用任一方法。两者都同样适用于这个目的。SQL 中通常有多种方式。有时没有明显的赢家。

这里关于性能的更重要的问题是:

每个周期完成 10 万次这样的 INSERT

对于大批量插入,INSERT在两个表中而不是为每一行触发触发器会更快。

如果您使用的是自动生成的串行 PK,则可以RETURNING在数据修改 CTE 中使用该子句

WITH ins1 AS (
   INSERT INTO measurement (measurement)
   VALUES ...   -- OR SELECT ... if data comes from inside the DB :)
   RETURNING measurement_id  -- generating a serial ID?
   )
INSERT INTO file_headers (measurement_id, file_header_index_start, file_header_index_end)
SELECT measurement_id,  1, 666  -- here it *must* be SELECT
FROM   ins1;
Run Code Online (Sandbox Code Playgroud)

666(没有引号,只有数字)这样的数字常量默认自动输入整数。

可能不适用,具体取决于您的工作流程。

有关的: