[PostgreSQL on EC2] pg_stat_statements を有効化してみた

[PostgreSQL on EC2] pg_stat_statements を有効化してみた

2026.03.16

PostgreSQL において pg_stat_statements を有効化すると以下のような情報が得られます。

  • 頻繁に実行されるクエリ
  • 累積的に実行時間が最も長いクエリ
  • 各クエリ実行の平均時間

今回はこれらを確認できるように実際に pg_stat_statements を有効化してみました。

※ 本記事では有効化手順に絞って解説します。pg_stat_statements の統計情報の詳しい見方や使い方などは別途調べてみてください(いずれブログ書けたらいいな...)

環境準備

前提として、パブリックサブネット配置の EC2(AL2023) に PostgreSQL サーバーはインストール済みとします。
インストール方法は以下を参照ください。下記ブログでは PostgreSQL 17 をインストールしています。
https://dev.classmethod.jp/articles/installing-postgresql-on-ec2-al2023/

また、pg_stat_statements を使うには、contrib パッケージのインストールが必要です。
そのため、上記ブログ内容に加えて、以下も実行しておきます。バージョン番号は適宜修正してください。

# contrib パッケージのインストール
$ sudo dnf install postgresql17-contrib -y

今回は PostgreSQL 17.7 を利用し、検証していきます。

環境確認
[ec2-user@ip-10-0-13-178 ~]$ sudo -u postgres psql
psql (17.7)
Type "help" for help.

postgres=# select * from version();
                                                   version                                                    
--------------------------------------------------------------------------------------------------------------
 PostgreSQL 17.7 on x86_64-amazon-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit
(1 row)

やってみた

まず EC2 インスタンスに接続し、PostgreSQL サーバーが起動しているか確認します。
下記の通り、Active: active (running) なので OK です。もし起動していなければ sudo systemctl start postgresql で起動します。

PostgreSQL が起動しているか確認
# PostgreSQL サーバーが起動しているか確認 -> OK
[ec2-user@ip-10-0-12-232 ~]$ sudo systemctl status postgresql
...
     Active: active (running) since Thu 2026-02-26 07:02:09 UTC; 4s ago
...

pg_stat_statements は PostgreSQL の Extension(拡張機能)です。
以下の通り、デフォルトでは無効になっており、利用するには有効化が必要です。

現時点では pg_stat_statements は使えない
# postgresql に接続
[ec2-user@ip-10-0-12-232 ~]$ sudo -u postgres psql
psql (17.7)
Type "help" for help.

-- pg_stat_statements が使える状態になっているか確認 -> 表示が空なので使える状態にない
postgres=# SHOW shared_preload_libraries;
 shared_preload_libraries 
--------------------------

(1 row)

-- pg_stat_statements ビューも現時点では存在せず、クエリができない
postgres=# SELECT count(*) FROM pg_stat_statements;
ERROR:  relation "pg_stat_statements" does not exist
LINE 1: SELECT count(*) FROM pg_stat_statements;

pg_stat_statements を有効化するために設定を入れます。やることは以下の 2 つです。

  • postgresql.conf にて pg_stat_statements 設定を追加
  • CREATE EXTENSION で有効化

以下、設定していきます。まず postgresql.conf ファイルがどこにあるのかわからないので、場所を確認します。

postgresql.conf ファイルがどこにあるのかを確認
-- postgresql.conf ファイルの場所を確認
postgres=# SHOW config_file;
             config_file             
-------------------------------------
 /var/lib/pgsql/data/postgresql.conf
(1 row)

-- PostgreSQL から抜ける
postgres=# \q

postgresql.conf の場所が確認できたら、実際に中身を編集していきます。
追加する設定は以下の 2 つです。

shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all

shared_preload_libraries は PostgreSQL の起動時に読み込む Extension を指定する設定です。
また pg_stat_statements.track は統計を記録する対象を指定するものです。all とすることで、全てのクエリを対象とします。
それぞれの詳細は下記ドキュメントを参照ください。

pg_stat_statementsモジュールは、サーバで実行されたすべてのSQL文のプラン生成時と実行時の統計情報を記録する手段を提供します。
このモジュールは追加の共有メモリを必要とするため、postgresql.confのshared_preload_librariesにpg_stat_statementsを追加してモジュールをロードしなければなりません。 このことは、このモジュールを追加もしくは削除するには、サーバを再起動する必要があるということを意味しています。
...
pg_stat_statements.track (enum)
pg_stat_statements.trackは、どのSQL文をモジュールによって計測するかを制御します。 topを指定した場合は(直接クライアントによって発行された)最上層のSQL文を記録します。 allは(関数の中から呼び出された文などの)入れ子になった文も記録します。

https://www.postgresql.jp/document/17/html/pgstatstatements.html

では実際に postgresql.conf を編集していきます。

postgresql.conf の編集
# vim でファイルを編集し保存
[ec2-user@ip-10-0-12-232 ~]$ sudo vi /var/lib/pgsql/data/postgresql.conf

# ちゃんと変更できたか確認 -> OK
[ec2-user@ip-10-0-12-232 ~]$ sudo grep pg_stat_statements /var/lib/pgsql/data/postgresql.conf
shared_preload_libraries = 'pg_stat_statements'		# (change requires restart)
pg_stat_statements.track = all

# 設定を PostgreSQL サーバーに反映させるために再起動
[ec2-user@ip-10-0-12-232 ~]$ sudo systemctl restart postgresql

# PostgreSQL に接続し、有効化されているか確認 -> OK
[ec2-user@ip-10-0-12-232 ~]$ sudo -u postgres psql
psql (17.7)
Type "help" for help.

-- pg_stat_statements が追加されている
postgres=# SHOW shared_preload_libraries;
 shared_preload_libraries 
--------------------------
 pg_stat_statements
(1 row)

-- だけどまだ pg_stat_statements ビューはクエリができない
postgres=# SELECT count(*) FROM pg_stat_statements;
ERROR:  relation "pg_stat_statements" does not exist
LINE 1: SELECT count(*) FROM pg_stat_statements;
補足:restart コマンド時にエラーになる場合

設定反映のための再起動 sudo systemctl restart postgresql にて以下のようなエラーになる場合があります。

[ec2-user@ip-10-0-12-232 ~]$ sudo systemctl restart postgresql
Job for postgresql.service failed because the control process exited with error code.
See "systemctl status postgresql.service" and "journalctl -xeu postgresql.service" for details.

上記エラーの原因は contrib パッケージのインストールし忘れの可能性があるので、sudo dnf install postgresql17-contrib -y などで入れてから再度やり直してみてください。

続いて、pg_stat_statements を有効化するために 以下の CREATE EXTENSION コマンドを使用します。

CREATE EXTENSION pg_stat_statements;

CREATE EXTENSION は接続しているデータベースでのみ有効化されるので、今回はデフォルトで接続される postgres データベース上で有効化を行います。

実際に有効化をしていきます。

-- 現在はデータベース postgres に接続している
postgres=# \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/var/run/postgresql" at port "5432".

-- pg_stat_statements を使えるようにする
postgres=# CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION

-- pg_stat_statements ビューがクエリできるようになった!
postgres=# SELECT count(*) FROM pg_stat_statements;
 count 
-------
    27
(1 row)

上記の通り、有効化ができました。
pg_stat_statements のクエリ結果が 27 となっていますが、これは PostgreSQL 内部のセットアップクエリが記録されているためです。特に気にしないで OK です。

pg_stat_statements がクエリできるようになると、実行したクエリの実行時間などがわかるようになります。
試しに簡単な動作確認をしてみます。
以下で最初に実行している pg_stat_statements_reset 関数についてはドキュメントを参照ください。

-- 今後実行するクエリ結果を見やすくするために、統計情報をリセットする
postgres=# SELECT pg_stat_statements_reset();
   pg_stat_statements_reset    
-------------------------------
 2026-03-16 07:51:02.151901+00
(1 row)

-- 同じクエリを3回実行してみる
postgres=# SELECT 1;
 ?column? 
----------
        1
(1 row)

postgres=# SELECT 1;
 ?column? 
----------
        1
(1 row)

postgres=# SELECT 1;
 ?column? 
----------
        1
(1 row)

-- pg_stat_statements で統計情報を確認する
postgres=# SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY calls DESC
LIMIT 5;
               query               | calls | total_exec_time | mean_exec_time 
-----------------------------------+-------+-----------------+----------------
 SELECT $1                         |     3 |        0.016155 |       0.005385
 SELECT pg_stat_statements_reset() |     1 |         0.09577 |        0.09577
(2 rows)

上記より SELECT $1 の calls が 3 となっており、SELECT 1 を 3 回実行したことが記録されています。
また、SELECT 1 の平均実行時間(mean_exec_time)と 3 回分の合計実行時間(total_exec_time)もわかりますね。
とても便利そうです。今後はこれらも使いながらクエリのパフォーマンスなんかも見ていきたいですね。

今回は pg_stat_statements の有効化と簡単な動作確認までを行いました。検証は以上です。

終わりに

今回は pg_stat_statements を有効化しました。セットアップの手順をまとめると以下の通りです。

  1. postgresql.conf に設定を追加する
  2. PostgreSQL を再起動する
  3. CREATE EXTENSION で有効化する

今後は実際にサンプルデータを用意して、統計情報の見方を学んでいきたいです。

本ブログがどなたかのお役に立てば幸いです。お疲れ様でした。

参考情報

https://dev.classmethod.jp/articles/installing-postgresql-on-ec2-al2023/
https://www.postgresql.jp/document/17/html/pgstatstatements.html
https://www.crunchydata.com/blog/tentative-smarter-query-optimization-in-postgres-starts-with-pg_stat_statements

この記事をシェアする

FacebookHatena blogX

関連記事