Running EXPLAIN ANALYZE on functions
有时候看看函数内部的 Postgres 查询计划会有帮助。问题是,对一个函数运行 EXPLAIN ANALYZE 通常只会显示一个 函数扫描 或结果节点,这对查询性能几乎没有什么洞察。
🌐 Sometimes it can help to look at Postgres query plans inside a function. The problem is that running EXPLAIN ANALYZE on a function usually shows a function scan or result node, which gives little insight into how the queries perform.
auto_explain 是一个预装模块,可以记录函数中查询的查询计划。
auto_explain 还有一些设置你需要配置一下:
auto_explain.log_nested_statements:在函数中记录查询的计划auto_explain.log_analyze:捕获explain analyze结果而不是explainauto_explain.log_min_duration:如果预计查询运行时间会超过设置的阈值,就记录计划
在大范围更改这些设置可能会导致过多的日志记录。相反,你可以使用 set local 命令在 begin/rollback 块中更改配置。这确保了更改仅限于该事务,并且测试期间的任何写入都会被撤销。
🌐 Changing these settings at a broad scale can lead to excessive logging. Instead, you can change the configs within a begin/rollback block with the set local command. This ensures the changes are isolated to the transaction, and any writes made during testing are undone.
begin;set local auto_explain.log_min_duration = '0'; -- log all query plansset local auto_explain.log_analyze = true; -- use explain analyzeset local auto_explain.log_buffers = true; -- use explain (buffers)set local auto_explain.log_nested_statements = true; -- log query plans in functionsselect example_func(); ---<--ADD YOUR FUNCTION HERErollback;如果需要,你可以为特定角色更改这些设置,但我们不建议长时间将下面的值设置为 1s,因为这可能会影响性能。
🌐 If needed, you can change these settings for specific roles, but we don't recommend configuring the value below 1s for extended periods, as it may degrade performance.
例如,你可以更改认证器角色的值(为数据 API 提供支持)。
🌐 For instance, you could change the value for the authenticator role (powers the Data API).
ALTER ROLE postgres SET auto_explain.log_min_duration = '.5s';在运行你的测试之后,你应该能够在 Postgres 日志 中找到该计划。auto_explain 模块的日志总是以“duration:”开头,你可以用这个作为筛选关键词。
🌐 After running your test, you should be able to find the plan in the Postgres logs. The auto_explain module always starts logs with the term "duration:", which can be used as a filter keyword.
你也可以在 SQL 编辑器 中使用以下查询来筛选特定功能:
🌐 You can also filter for the specific function in the SQL Editor with the below query:
select timestamp, event_message as query_and_plan, log_attributes['parsed.user_name'] as user_name, log_attributes['parsed.context'] as contextfrom logswhere source = 'postgres_logs' and match(event_message, 'duration:') and match(log_attributes['parsed.context'], '(?i)FUNCTION_NAME')order by timestamp desclimit 100;