如何在 postgresql 中获取正在运行的查询的执行计划?

Posted

技术标签:

【中文标题】如何在 postgresql 中获取正在运行的查询的执行计划?【英文标题】:How to get execution plan for a running query in postgresql? 【发布时间】:2017-08-24 13:11:27 【问题描述】:

我有一个未优化的查询,它在一天中的不同时间运行一系列不同的执行时间,从 1 分钟到 14 小时不等。数据库上的 CPU 利用率、内存和其他并发负载保持不变,什么会导致这种变化?请注意,自动真空过程在午夜运行,而性能在早上显着提高。我的断言是,由于表碎片、死元组和大量读取,同一张表上的统计信息会发生变化,从而产生不同的执行计划。为了证明这个断言,我想获得当前正在运行的查询的查询计划。请注意,我不可能在执行前简单地EXPLAIN 查询。

【问题讨论】:

postgresql.org/docs/current/static/auto-explain.html AFAIU,这将需要重新启动数据库,这也不是一个选项。此外,这会产生为所有长时间运行的查询而不仅仅是相关查询生成查询计划的开销。 1:这不需要重新启动,最多重新加载。 2:无论如何,PostgreSQL 必须为每个查询生成查询计划(除非它已经准备好,那么它只生成一次计划)。 3:这里唯一的开销是记录查询计划,这是最小的。只需将 auto_explain.log_min_duration 设置为类似 10000 的 simethung,因此它必须是 10 秒查询等。 请注意,您可以加载扩展,设置 auto_explain.log_min_duration 直到错误查询结束,然后将其设置回 -1 以将其关闭。 @ScottMarlowe 确实,您说得对,不需要重新启动。但是如何将其应用于所有会话。那不需要重启吗? 【参考方案1】:

等我搞定了。在 postgresql.conf 中有两个用于预加载库的设置。第一个,shared_preload_libraries,如果不重新启动将无法工作。但是另一个 session_preload_libraries 会。因此,编辑 postgresql.conf 以在其中包含这一行:

session_preload_libraries = 'auto_explain'

然后重新加载:

pg_ctl reload (or pg_ctlcluster 9.x main reload etc)

然后更改数据库以将其打开:

alter database smarlowe set auto_explain.log_min_duration=1;

然后所有新连接都会获得自动解释计划。

将持续时间更改为对您最有意义的毫秒设置。

【讨论】:

以上是关于如何在 postgresql 中获取正在运行的查询的执行计划?的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个 php 文件中使用 PostgreSql 的 CURRVAL / RETURNING?

PostgreSQL:如何在函数中并行运行查询?

如何通过 ODBC 在 Access 中获取详细的 PostgreSQL 错误?

如何在 postgresql 中改进此查询?它已经花费了超过 48 小时

在PostgreSQL查询中获取大对象的大小?

PostgreSQL如何对结果进行分组以使所有行都必须为真?