当我的PLPGSQL
函数(Postgres 9.6)中的一条语句正在运行时,我可以在一行上看到查询,然后在另一行上看到所有参数。2行记录。就像是:
LOG: execute <unnamed>: SELECT * FROM table WHERE field1=$1 AND field2=$2 ...
DETAIL: parameters: $1 = '-767197682', $2 = '234324' ....
是否有可能登陆pg_log整个查询WITH参数已经在查询替换,并在其记录单行?
因为这将使复制/粘贴查询以在另一个终端中重现它变得更加容易,尤其是在查询具有数十个参数的情况下。
其背后的原因:PL / pgSQL在内部将SQL语句视为已准备好的语句。
第一:使用默认设置时,在PL / pgSQL函数中根本不记录SQL语句。您正在使用auto_explain
吗?
在同一会话中的前两次调用中,SPI管理器(服务器编程接口)根据实际参数值生成新的执行计划。任何类型的日志记录都应内联报告参数值。
Postgres会跟踪当前会话中的几次调用,如果执行计划对实际参数值似乎不敏感,它将开始重新使用通用的缓存计划。然后,您应该看到带有$n
参数的预准备语句的通用计划(如问题中所示)。
手册中“计划缓存”一章中的详细信息。
您可以通过一个简单的演示来观察效果。在同一会话中(不一定是同一笔交易):
CREATE TEMP TABLE tbl AS
SELECT id FROM generate_series(1, 100) id;
PREPARE prep1(int) AS
SELECT min(id) FROM tbl WHERE id > $1;
EXPLAIN EXECUTE prep1(3); -- 1st execution
您将看到实际值:
Filter: (id > 3)
EXECUTE prep1(1); -- several more executions
EXECUTE prep1(2);
EXECUTE prep1(3);
EXECUTE prep1(4);
EXECUTE prep1(5);
EXPLAIN EXECUTE prep1(3);
现在,您将看到一个$n
参数:
Filter: (id > $1)
因此,您可以在当前会话的前两次调用中获得内联参数值的查询。
或者,您可以将动态SQL与一起使用EXECUTE
,因为根据文档:
另外,没有计划缓存通过来执行的命令
EXECUTE
。而是总是在每次运行语句时计划命令。因此,可以在函数中动态创建命令字符串,以对不同的表和列执行操作。
当然,这实际上会影响性能。
有关的:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句