pg_show_plans

1. 概述

pg_show_plans 是一个 PostgreSQL 扩展,用于显示当前所有正在运行的 SQL 语句的查询计划。查询计划可以以多种格式展示,包括 TEXTJSONYAML

该扩展在共享内存中创建哈希表。哈希表大小不可动态调整——一旦填满,将无法添加新的查询计划记录。

2. 安装

源码安装环境为 Ubuntu 24.04(x86_64),环境中已安装 IvorySQL 5 及以上版本,安装路径为 /usr/ivory-5

2.1. 源码安装

在开始之前,请确保 pg_config 可在 PATH 中访问。

git clone https://github.com/cybertec-postgresql/pg_show_plans.git
cd pg_show_plans

make PG_CONFIG=/usr/ivory-5/bin/pg_config
make PG_CONFIG=/usr/ivory-5/bin/pg_config install

2.2. 配置 shared_preload_libraries

ivorysql.conf 中将 pg_show_plans 添加到 shared_preload_libraries 参数:

shared_preload_libraries = 'liboracle_parser, ivorysql_ora, pg_show_plans'

重启 IvorySQL 实例使配置生效:

pg_ctl restart -D data

2.3. 创建扩展

服务器重启后,连接到目标数据库并创建扩展:

CREATE EXTENSION pg_show_plans;

3. 使用方法

3.1. 查看当前查询计划

使用 pg_show_plans 视图,可以查看所有当前正在运行的 SQL 语句的执行计划:

SELECT * FROM pg_show_plans;
  pid  | level | userid | dbid  |                                 plan
-------+-------+--------+-------+-----------------------------------------------------------------------
 11473 |     0 |     10 | 16384 | Function Scan on pg_show_plans  (cost=0.00..10.00 rows=1000 width=56)
 11504 |     0 |     10 | 16384 | Function Scan on print_item  (cost=0.25..10.25 rows=1000 width=524)
 11504 |     1 |     10 | 16384 | Result  (cost=0.00..0.01 rows=1 width=4)
(3 rows)

3.2. 同时查看查询计划与 SQL 语句

使用 pg_show_plans_q 视图,可以同时查看查询计划和对应的 SQL 语句。该视图将 pg_show_planspg_stat_activity 进行关联:

SELECT * FROM pg_show_plans_q;
-[ RECORD 1 ]------------------------------------------------------------------------------------
pid   | 11473
level | 0
plan  | Sort  (cost=72.08..74.58 rows=1000 width=80)
      |   Sort Key: pg_show_plans.pid, pg_show_plans.level
      |   ->  Hash Left Join  (cost=2.25..22.25 rows=1000 width=80)
      |         Hash Cond: (pg_show_plans.pid = s.pid)
      |         Join Filter: (pg_show_plans.level = 0)
      |         ->  Function Scan on pg_show_plans  (cost=0.00..10.00 rows=1000 width=48)
      |         ->  Hash  (cost=1.00..1.00 rows=100 width=44)
      |               ->  Function Scan on pg_stat_get_activity s  (cost=0.00..1.00 rows=100 width=44)
query | SELECT p.pid, p.level, p.plan, a.query FROM pg_show_plans p
      |    LEFT JOIN pg_stat_activity a
      |    ON p.pid = a.pid AND p.level = 0 ORDER BY p.pid, p.level;
-[ RECORD 2 ]------------------------------------------------------------------------------------
pid   | 11517
level | 0
plan  | Function Scan on print_item  (cost=0.25..10.25 rows=1000 width=524)
query | SELECT * FROM print_item(1,20);
-[ RECORD 3 ]------------------------------------------------------------------------------------
pid   | 11517
level | 1
plan  | Result  (cost=0.00..0.01 rows=1 width=4)
query |