queryid,query FROM pg_stat_statements; queryid | query ---------------------+------------------------------------------------------------------- -375957924471267726 | SELECT n.nspname as "Schema", | c.relname as "Name", | CASE c.relkind WHEN $1 THEN $2 WHEN $3 THEN $4 WHEN $5 THEN $6 | WHEN $7 THEN $8 WHEN $9 THEN $10 WHEN $11 THEN $12 WHEN $13 | THEN $14 WHEN $15 THEN $16 WHEN $17 THEN $18 END as "Type", | pg_catalog.pg_get_userbyid(c.relowner) as "Owner" | FROM pg_catalog.pg_class c | LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace | LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam | WHERE c.relkind IN ($19 /*, ... */) | AND n.nspname <> $20 AND n.nspname !~ $21 AND n.nspname <> $22 | AND pg_catalog.pg_table_is_visible(c.oid) | ORDER BY 1,2 たとえば、以下のようなSQLの情報収集をするとき、 queryをそのまま検索条件として指定したり、 他テーブルとの結合条件にSQL全文を指定するのは非常に面倒です。 query_idがあれば、この識別子だけで特定SQLの情報収集が可能となります。
queryid,query FROM pg_stat_statements WHERE query LIKE '%SELECT n.nspname%'; queryid | query ---------------------+------------------------------------------------------------------- -375957924471267726 | SELECT n.nspname as "Schema", | c.relname as "Name", | CASE c.relkind WHEN $1 THEN $2 WHEN $3 THEN $4 WHEN $5 THEN $6 | WHEN $7 THEN $8 WHEN $9 THEN $10 WHEN $11 THEN $12 WHEN $13 | THEN $14 WHEN $15 THEN $16 WHEN $17 THEN $18 END as "Type", | pg_catalog.pg_get_userbyid(c.relowner) as "Owner" | FROM pg_catalog.pg_class c | LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace | LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam | WHERE c.relkind IN ($19 /*, ... */) | AND n.nspname <> $20 AND n.nspname !~ $21 AND n.nspname <> $22 | AND pg_catalog.pg_table_is_visible(c.oid) | ORDER BY 1,2 あるqueryのquery_idを特定したい場合、最初はquery列にSQLの情報を 検索条件に指定するなどして特定していく必要がありますが、1度確認できれば 同一環境であればこれ以降はquery_idを使って特定SQLの情報収集ができます。 類似のSQLが大量にある場合、query列だけで絞り込むのは中々大変です。
同一のquery_idとなるようジャンブリング処理が変更されています。 PostgreSQL 17以前では、それぞれ異なるquery_idで出力されます。 ## PostgreSQL 18.0 postgres=# explain(analyze,buffers,verbose) SELECT * FROM test1 WHERE id1 IN (1); Query Identifier: 1180084584667567685 postgres=# explain(analyze,buffers,verbose) SELECT * FROM test1 WHERE id1 IN (1,2); Query Identifier: -1145653792731238719 postgres=# explain(analyze,buffers,verbose) SELECT * FROM test1 WHERE id1 IN (1,2,3); Query Identifier: -1145653792731238719 ## PostgreSQL 17.6 postgres=# explain(analyze,buffers,verbose) SELECT * FROM test1 WHERE id1 IN (1); Query Identifier: 1873785992871691032 postgres=# explain(analyze,buffers,verbose) SELECT * FROM test1 WHERE id1 IN (1,2); Query Identifier: 7527615588110704768 postgres=# explain(analyze,buffers,verbose) SELECT * FROM test1 WHERE id1 IN (1,2,3); Query Identifier: -972988021940978450
PostgreSQL 18では、拡張機能との連携を目的として、 「拡張機能によって計算したplan_idをプランナ情報にセットする」 ことができるようになっています。 Allow plugins to set a 64-bit plan identifier in PlannedStmt https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2a0cd38da5ccf70461c51a489ee7d25fcd3f26be これによって、拡張機能pg_stat_plans(v2.0)では、 実行計画・plan_idに関する情報を蓄積するだけでなく、 「特定プロセスで実行中のSQLのplan_idを確認する」ことができます。