Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 为什么auto_在第一次调用PL/pgSQL函数时只解释日志嵌套语句?_Postgresql_Logging_Sql Execution Plan - Fatal编程技术网

Postgresql 为什么auto_在第一次调用PL/pgSQL函数时只解释日志嵌套语句?

Postgresql 为什么auto_在第一次调用PL/pgSQL函数时只解释日志嵌套语句?,postgresql,logging,sql-execution-plan,Postgresql,Logging,Sql Execution Plan,在我的Postgres服务器上,我使用带有log\u嵌套语句的auto\u explain模块来记录PL/pgSQL函数中的其他函数调用 594 session_preload_libraries = 'auto_explain' 595 596 auto_explain.log_min_duration = 0 597 auto_explain.log_nested_statements = true 598 auto_explain.sample_rate = 1.0 我有一个玩具PL/p

在我的Postgres服务器上,我使用带有
log\u嵌套语句的
auto\u explain
模块来记录PL/pgSQL函数中的其他函数调用

594 session_preload_libraries = 'auto_explain'
595
596 auto_explain.log_min_duration = 0
597 auto_explain.log_nested_statements = true
598 auto_explain.sample_rate = 1.0
我有一个玩具PL/pgSQL函数
baz(countint)

在数据库连接中第一次调用函数
baz(1)
时,我看到每个嵌套语句都记录为计划的一部分:

2019-03-19 15:25:05.765 PDT [37616] LOG:  statement: select baz(1);
2019-03-19 15:25:05.768 PDT [37616] LOG:  duration: 0.002 ms  plan:
    Query Text:  SELECT 'bar'
    Result  (cost=0.00..0.01 rows=1 width=32)
2019-03-19 15:25:05.768 PDT [37616] CONTEXT:  SQL function "bar" statement 1
    SQL function "foo" during startup
    SQL statement "SELECT result || ' ' || foo()"
    PL/pgSQL function foo(integer) line 14 at assignment
2019-03-19 15:25:05.768 PDT [37616] LOG:  duration: 0.001 ms  plan:
    Query Text:  SELECT 'foo ' || bar()
    Result  (cost=0.00..0.01 rows=1 width=32)
2019-03-19 15:25:05.768 PDT [37616] CONTEXT:  SQL function "foo" statement 1
    SQL statement "SELECT result || ' ' || foo()"
    PL/pgSQL function foo(integer) line 14 at assignment
2019-03-19 15:25:05.768 PDT [37616] LOG:  duration: 0.952 ms  plan:
    Query Text: select baz(1);
    Result  (cost=0.00..0.26 rows=1 width=32)
但是,当我在同一连接上再次调用该函数时,在日志中看不到嵌套语句:

2019-03-19 15:29:06.608 PDT [37616] LOG:  statement: select baz(1);
2019-03-19 15:29:06.608 PDT [37616] LOG:  duration: 0.046 ms  plan:
    Query Text: select baz(1);
    Result  (cost=0.00..0.26 rows=1 width=32)

为什么会这样?在同一数据库连接过程中,如何在函数的后续调用中记录嵌套语句?

您可以这样做,以便每次记录语句:

ALTER FUNCTION foo() STABLE;
但是你的表现会受到一些影响

解开谜团:

  • PL/pgSQL函数中调用的SQL语句的执行计划在数据库会话的生命周期内被缓存,因此当函数第一次执行时,它们只被解析一次

  • 不可变的
    表达式在解析SQL语句并将其转换为常量时进行计算

仅第一次记录的语句是仅在解析
baz
中的SQL语句时才计算的语句

2019-03-19 15:29:06.608 PDT [37616] LOG:  statement: select baz(1);
2019-03-19 15:29:06.608 PDT [37616] LOG:  duration: 0.046 ms  plan:
    Query Text: select baz(1);
    Result  (cost=0.00..0.26 rows=1 width=32)
ALTER FUNCTION foo() STABLE;