Skip to main content
© 2021 NTT DATA Corporation
PostgreSQL 14の”pg_stat_statements”改善
2021年5月11日 第23回PostgreSQLアンカンファレンス@オンライン
株式会社NTTデータ 技術開発本部
清野 裕貴
2
© 2021 NTT DATA Corporation
本講演について
講演資料は、NTTデータのSlideShareアカウント上で公開予定です。
https://www.slideshare.net/nttdata-tech
3
© 2021 NTT DATA Corporation
自己紹介
清野 裕貴
@NTTデータ
現在
PostgreSQL研究開発、社内普及展開
これまで
公共系プロジェクトのPM/AP要件定義・設計の業務に従事
※使用していたRDBMSはOracle Database 11g,12c
何か一つの分野を極めたい
社内の資格取得のために取得した「OSS-DB
Gold」をきっかけに、社内OSSチームに参加
@YukiSeino
4
© 2021 NTT DATA Corporation
PostgreSQL 14
• 現在コミュニティで開発中の最新バージョン
• Feature Freeze済み(2021.4.7 AoE※)
• 5月にβ1、10~11月に正式リリースの予定
※ AoE:世界で最も西の標準時(地球上で最も遅いタイムゾーン)
今回ご紹介する機能は正式リリースまでに
変更になる可能性があるのでご注意ください。
5
© 2021 NTT DATA Corporation
本日のアジェンダ
本日はPostgreSQL 14に反映予定の”pg_stat_statements”の新機能2点をご紹介。
• “pg_stat_statements” とは?
• 新機能1:”pg_stat_statements_info”ビューの追加
[pg_stat_statements: Track time at which all statistics were last reset.]
[pg_stat_statements: Track number of times pgss entries were deallocated.]
• 新機能2:処理行数を出力できるSQLコマンドの拡充
[pg_stat_statements: track number of rows processed by some utility commands.]
• さいごに
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=6023b7ea717ca04cf1bd
53709d9c862db07eaefb
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2e0fedf0362cc964c4dae
42258455b6391051e70
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=9fbc3f318d039c3e1e861
4c38e40843cf8fcffde
© 2021 NTT DATA Corporation
“pg_stat_statements” とは?
7
© 2021 NTT DATA Corporation
“pg_stat_statements” とは?
• PostgreSQLから拡張機能(contrib)の形で提供
• 実行されたSQLの実行時の統計情報を記録し、確認するためのビューを提供
⇒ ビューからは、 ”実行されたSQL文”や“実行回数”、“実行に費やした時間”等を確認可能。
• 遅延SQLの発見やSQLチューニングの元ネタになるため、実際の現場で有用
⇒ クラウドDB(“Amazon RDS” や ”Azure Database for PostgreSQL”)でも
使用可能な拡張機能の位置づけ。
• Oracle DatabaseにおけるV$SQLに該当
8
© 2021 NTT DATA Corporation
“pg_stat_statements” とは?
• その他、導入方法や詳細機能については、PostgreSQL公式マニュアルを参照してください。
<PostgreSQL 13マニュアル(英文)>
https://www.postgresql.org/docs/13/pgstatstatements.html
<PostgreSQL 12.4 日本語マニュアル>
https://www.postgresql.jp/document/12/html/pgstatstatements.html
※develもあります。(今回紹介する機能も反映済み)
https://www.postgresql.org/docs/devel/pgstatstatements.html
© 2021 NTT DATA Corporation
新機能1
”pg_stat_statements_info”ビューの追加
10
© 2021 NTT DATA Corporation
新機能1:”pg_stat_statements_info”ビューの追加
“pg_stat_statements” では、パラメータ“pg_stat_statements.max”にて保持する情報量
(エントリ数)のmaxを設定することができます。maxを超えるエントリがあった場合には、実行回数の少
ないSQLから順番に既存エントリを削除します。
postgres=# SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
query | calls | rows
--------------------------------------------------------+-------+------
BEGIN | 1 | 0
COMMIT | 1 | 0
DECLARE pgss_cursor CURSOR FOR SELECT * FROM pgss_matv | 1 | 0
FETCH FORWARD 5 pgss_cursor | 1 | 5
FETCH FORWARD ALL pgss_cursor | 1 | 7
FETCH NEXT pgss_cursor | 1 | 1
SELECT pg_stat_statements_reset() | 1 | 1
pg_stat_statemnents.max
11
© 2021 NTT DATA Corporation
新機能1:”pg_stat_statements_info”ビューの追加
エントリ削除を行う際にはオーバヘッド(スキャン、ソート、削除処理)が発生しますが、処理中にエントリ全体をロック
してしまうため、他SQL実行があった際の統計情報登録時にロック待ちが生じます。
従って、エントリ削除が頻繁に発生するような場合には、深刻な性能劣化が発生する可能性があります。
※pg_stat_statements.cのエントリ削除箇所抜粋
性能劣化を発生させないためには、実運用の状況に応じて”pg_stat_statements.max”をチューニングする必要
がありますが、PostgreSQL 13以前では、エントリ数がmaxを超えた頻度を把握する手段がありません。
これに対応するために、PostgreSQL 14では
“pg_stat_statements_info”ビューが追加されました。
ソート
エントリ削除
スキャン
12
© 2021 NTT DATA Corporation
新機能1:”pg_stat_statements_info”ビューの追加
“pg_stat_statements_info”ビューが追加されました。(2つの情報が追加されました。)
postgres=# SELECT * FROM pg_stat_statements_info;
dealloc | stats_reset
---------+-------------------------------
6 | 2021-04-20 09:57:40.853551+09
<dealloc>
エントリ削除が発生した回数の累計を表示します。
この項目はpg_stat_statements_resetによりリセットされます。
※ pg_stat_statements.maxのデフォルト値は5000
【注意点】
あくまで累計回数でしかないので、
エントリ削除の頻度を確認するに
は継続的に監視が必要です。
“pg_stat_statements”を利用していて、システムの性能低下が発生した場合は、
“pg_stat_statements_info.dealloc”でエントリ削除の頻度を確認し、
”pg_stat_statements.max”のチューニングを行ってください!
13
© 2021 NTT DATA Corporation
新機能1:”pg_stat_statements_info”ビューの追加
“pg_stat_statements”で保持している統計情報は累計のものなので、例えば単位時間当たりの情報(“SQL
実行回数“や前節で解説した”エントリ削除回数”など)を算出することができませんでした。
PostgreSQL 14以降では、 “pg_stat_statements_info”ビューに“stats_reset”カラムが追加され、統計
情報の取得開始日時が把握できるようになりました。
postgres=# SELECT * FROM pg_stat_statements_info;
dealloc | stats_reset
---------+-------------------------------
6 | 2021-04-20 09:57:40.853551+09
“pg_stat_statements”を利用していて、単位時間あたりの情報を算出したい場合は、
“pg_stat_statements_info.stats_reset”でリセット時間を確認してください!
<stats_reset>
pg_stat_statements_resetによりpg_stat_statementsが最後
にリセットされた時間を記録します。
【注意点】
pg_stat_statements_reset()や
pg_stat_statements_reset(0,0,0)など
すべての統計情報が削除対象となった
場合のみ記録。
© 2021 NTT DATA Corporation
新機能2
処理行数を出力できるSQLコマンドの拡充
15
© 2021 NTT DATA Corporation
新機能2:処理行数を出力できるSQLコマンドの拡充
”pg_stat_statements”ではステートメントで処理対象となった行数を出力することが可能です。
PostgreSQL 13以前では、処理対象行数(rows)の表示は、ユーティリティコマンドに
対応していませんでしたが、PostgreSQL 14では、以下のユーティリティコマンドについても、
処理対象行数を表示することができるようになりました。
・ “CREATE TABLE AS”
・ “SELECT INTO”
・ “COPY”
・ “CREATE MATERIALIZED VIEW” “REFRESH MATERIALIZED VIEW”
・ “FETCH”
各コマンドにおいて、処理対象となった行数を把握したい場合に有用です。
実運用でも多用されるSQL文に対するアップデートなので、ぜひお試しください。
16
© 2021 NTT DATA Corporation
改善点2:処理行数を出力できるSQLコマンドの拡充
“CREATE TABLE AS”
“SELECT INTO”
postgres=# CREATE TABLE pgss_ctas AS SELECT a, 'ctas' b FROM generate_series(1, 10) a;
SELECT 10
postgres=# SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
query | calls | rows
----------------------------------------------------------------------------+-------+------
CREATE TABLE pgss_ctas AS SELECT a, 'ctas' b FROM generate_series(1, 10) a | 1 | 10
SELECT pg_stat_statements_reset() | 1 | 1
(2 rows)
postgres=#
postgres=# SELECT generate_series(1, 10) c INTO pgss_select_into;
SELECT 10
postgres=# SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
query | calls | rows
-------------------------------------------------------+-------+------
SELECT generate_series(1, 10) c INTO pgss_select_into | 1 | 10
SELECT pg_stat_statements_reset() | 1 | 1
(2 rows)
postgres=#
pgss_ctas
a | b
----+-----
1 | ctas
2 | ctas
3 | ctas
4 | ctas
5 | ctas
6 | ctas
7 | ctas
8 | ctas
9 | ctas
10 | ctas
pgss_select_into
c
----
1
2
3
4
5
6
7
8
9
10
17
© 2021 NTT DATA Corporation
改善点2:処理行数を出力できるSQLコマンドの拡充
“COPY”
postgres=# COPY pgss_ctas (a, b) FROM STDIN;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 11 copy
>> 12 copy
>> 13 copy
>> .
COPY 3
postgres=# SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
query | calls | rows
-----------------------------------+-------+------
COPY pgss_ctas (a, b) FROM STDIN | 1 | 3
SELECT pg_stat_statements_reset() | 1 | 1
(2 rows)
postgres=#
pgss_ctas
a | b
----+------
1 | ctas
2 | ctas
3 | ctas
4 | ctas
5 | ctas
6 | ctas
7 | ctas
8 | ctas
9 | ctas
10 | ctas
11 | copy
12 | copy
13 | copy
18
© 2021 NTT DATA Corporation
改善点2:処理行数を出力できるSQLコマンドの拡充
“CREATE MATERIALIZED VIEW”
“REFRESH MATERIALIZED VIEW”
postgres=# CREATE MATERIALIZED VIEW pgss_matv AS SELECT * FROM pgss_ctas;
SELECT 13
postgres=# REFRESH MATERIALIZED VIEW pgss_matv;
REFRESH MATERIALIZED VIEW
postgres=# SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
query | calls | rows
---------------------------------------------------------------+-------+------
CREATE MATERIALIZED VIEW pgss_matv AS SELECT * FROM pgss_ctas | 1 | 13
REFRESH MATERIALIZED VIEW pgss_matv | 1 | 13
SELECT pg_stat_statements_reset() | 1 | 1
(3 rows)
postgres=#
pgss_matv
a | b
----+------
1 | ctas
2 | ctas
3 | ctas
4 | ctas
5 | ctas
6 | ctas
7 | ctas
8 | ctas
9 | ctas
10 | ctas
11 | copy
12 | copy
13 | copy
19
© 2021 NTT DATA Corporation
改善点2:処理行数を出力できるSQLコマンドの拡充
“FETCH”
BEGIN;
DECLARE pgss_cursor CURSOR FOR SELECT * FROM pgss_matv;
FETCH NEXT pgss_cursor;
~
FETCH FORWARD 5 pgss_cursor;
~
FETCH FORWARD ALL pgss_cursor;
~
COMMIT;
postgres=# SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
query | calls | rows
--------------------------------------------------------+-------+------
BEGIN | 1 | 0
COMMIT | 1 | 0
DECLARE pgss_cursor CURSOR FOR SELECT * FROM pgss_matv | 1 | 0
FETCH FORWARD 5 pgss_cursor | 1 | 5
FETCH FORWARD ALL pgss_cursor | 1 | 7
FETCH NEXT pgss_cursor | 1 | 1
SELECT pg_stat_statements_reset() | 1 | 1
(7 rows)
postgres=#
a | b
---+------
1 | ctas
(1 row)
a | b
---+------
2 | ctas
3 | ctas
4 | ctas
5 | ctas
6 | ctas
(5 rows)
a | b
----+------
7 | ctas
8 | ctas
9 | ctas
10 | ctas
11 | copy
12 | copy
13 | copy
(7 rows)
© 2021 NTT DATA Corporation
さいごに
21
© 2021 NTT DATA Corporation
さいごに
• PostgreSQL 14の新機能のうち、私自身が機能追加にも関わった”pg_stat_statements”の
改善について、ご紹介させていただきました。
• ”pg_stat_statements”は統計情報とイメージしやすく、拡張機能扱い
(PostgreSQL本体機能の外)であることから、初心者のパッチ作成やパッチレビューに断然おすすめです。
• V14βがリリースされた際には、ぜひ新機能を試していただければと思います。
© 2021 NTT DATA Corporation 22
YouTubeチャンネル “NTT DATA Tech”
技術取り組み、活用情報を中心にお届けします
https://www.youtube.com/NTTDATATech
© 2021 NTT DATA Corporation
その他、記載されている会社名、商品名、又はサービス名は、
各社の登録商標又は商標です。