ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

NTTDATATC2019「PostgreSQL 12 は ここがスゴイ!」聴講メモ

はじめに

NTTデータ テクノロジーカンファレンス 2019(NTTデータ テクノロジーカンファレンス 2019 ~ 未来を創る NTT DATA の確かな技術力 ~
【テクノロジーPostgreSQL 12 は ここがスゴイ!~性能改善や pluggable storage engine などの新機能を徹底解説~
スピーカー:NTT OSSセンタ Software Engineer 澤田 雅彦 氏 (PostgreSQL コントリビュータ)
の聴講メモです。

現時点で資料の公開はありませんが(今後公開される可能性はあるようです)、澤田さんが別の機会に登壇された際の資料が公開されており、今回の講演と内容の一部が重複していました。こちらをご参照ください。

【参考】としている個所は私が挿入しています(補足や参考資料など)。登壇者の講演内容ではありませんので、その旨ご了承ください。

聴講メモ

PostgreSQL 12 のリリース

PostgreSQL 12(以下、"12"のようにバージョンのみの略記とする)は2019年秋のリリース予定。現時点(2019/09)で12はベータ3の状態。2019/10にはリリースされるかも。

PostgreSQLは毎年メジャーバージョンがリリースされ、ほぼ同じリリーススケジュールになっている。

12のリリースと同時に9.4のコミュニティサポートが切れることに注意が必要となる。


【参考】
PostgreSQL: Versioning Policy
この記事公開時点で9.4のサポート停止は2020年02月13日となっています。最新の情報はリンク先でご確認ください。

12の特徴を下記に挙げる。

  • 既存機能の大幅改善
  • 将来の機能拡張への基盤
  • かゆいところに手の届く機能
  • 珍しく大きめの非互換

テーブル・パーティショニング

テーブル・パーティショニングの改善は12の改善全体の15パーセントを占めるぐらい活発に開発されている。

パーティション・テーブルへの外部キー制約が実現された。

パーティション・プルーニングの性能改善が行われた。これによりプランニングの時間が改善された。11でも早くなっていたが、子テーブル数に比例してプランニングの時間 O(log N) がかかっていた。12では数千の子テーブル数があっても時間がほとんどかからない。12ではプルーニング情報を求めた後に興味のある子テーブルの管理情報だけを作成するようになったため。

子テーブルの数が少ない内は11でも12でも大きな差は無いが、数千以上の子テーブルを持つような大規模な環境では有用となる。


【参考】
第2回「PostgreSQL11でのテーブル・パーティショニング機能の改善」 | NTTデータ先端技術株式会社
11での記事ですが、PostgreSQLパーティション・プルーニングの動作が解説されています。

CTE inlining

CTEとはSQLのWITH句のこと。再帰クエリに利用できたりする。

PostgreSQLの実装ではCTEの結果を常に一時テーブルとして保持している。これはワークメモリに格納され、そのサイズを超えるとディスクに書き出されて遅くなる。

11まではCTEとサブクエリで等価なクエリを書いても実行計画が異なっていた。CTEは常に一時テーブルを作る分遅くなるケースがあった。12ではCTEをインライン展開することでサブクエリの場合と同様に高速で処理することができる。

CTEのインライン展開は他のRDBMSでもデフォルトの動作になっている。なお、再帰などの場合はマテリアライズ(一時テーブル扱い)となる。また、MATERIALIZED句を使えば11以前の動きにできる。


【参考】
PostgreSQL 12の新機能:CTEの高速化
CTEについての概説と12での改善について解説されています。

VACUUM処理の改善

VACUUM処理は以下の順で進む。
(1) テーブルスキャン
Visibility Map でゴミのあるページを特定する。この処理は早い。
(2) インデックスVACUUM
1行でもゴミがあればインデックスをフルスキャンする。この処理は遅い。
(3) テーブルVACUUM
ゴミのあるページのみをVACUUMする。
(4) 末尾の切り詰め
共有バッファをフルスキャンする。この処理の間はテーブルをロックしているため、コンカレントにSELECTやUPDATE処理を行うことができない。この処理も長時間かかることがある。

VACUUMで時間のかかる処理に対応するためのオプションが増えた。
(1) INDEX_CLEANUPオプション
offだとインデックスが肥大化する可能性がある。大規模テーブルで頻繁に更新がかかるとか、定期的にreindexできるなら有効となる。
(2) TRUNCATEオプション
offにするとテーブルの物理サイズが小さくならない。高頻度で更新されたり、共有バッファが大きい場合は有効となる。


【参考】

□ インデックスに対する VACUUM 処理
WITH 句に VACUUM_INDEX_CLEANUP = OFF を指定することで、インデックスに対する VACUUM 処理を無効にすることができるようになりました。デフォルト値は ON で、従来通り VACUUM が行われます。
□ テーブル終端の空きブロック開放
テーブルの属性に VACUUM_TRUNCATE が追加されました。VACUUM 実行時にテーブル終端の空きブロックを解放するかを決定します。デフォルト値は ON で、従来と同様に空き領域を解放します。OFF に指定するとこの動作を行いません。

PostgreSQL 12 新機能検証結果 (Beta 1)



genelated columns

生成列とも呼ばれる。他の列情報から計算式によって値を生成する列のこと。計算した値が実際に格納される。都度計算するオプション(VIRTUAL)には非対応となっている。

create statistics

拡張統計情報について。PostgreSQLは行数推定で列の値の独立性を仮定している。これを事象の独立性という。


【参考】
「行数推定」と「事象の独立性」の関係については以下の資料が分かりやすいです。

例として住所テーブルを考えてみる。PostgreSQLは「都道府県」列と「市町村」列を独立していると仮定しているが、実際には「東京都」と「千代田区」は関連しているように、これらの列が独立とは言えない。結果として行数推定が過少見積もりになってしまう。

この問題に対応するため、相関関係のある複数列にまたがった統計情報をとれるようになった。この機能は10からあったが、12からは最頻値もとれるようになった。

プラガブル・ストレージ・エンジン

PostgreSQLに独自のテーブル構造を組み込めるようになった。Oracleのような更新型(追記型でない)エンジンとか、インメモリのエンジンを組み込めるようになる。

同じくエンジンを差し替えられるMySQLとの違いとして、PostgreSQLではテーブル操作に関わる部分だけ差し替えられるようになっている。これにより、独自エンジンでもPostgreSQLの既存機能を利用可能となっている。

影響の大きそうな非互換

with oids が廃止になる。PostgreSQL の OID は Oracle の ROWNUM のような使い方ができたが、今後はこれができなくなる。with oids があるテーブルはそのままアップグレードできないことに注意。

recovery.conf が postgresql.conf に統合された。これによりリカバリー設定をreloadで反映できるなど恩恵がある。
12以降は recovery.conf があると起動しない。運用やバックアップツールの改修が必要となる。


【参考】
PostgreSQL 12 新機能検証結果 (Beta 1)
3.1.2. recovery.conf ファイルの廃止
この章に解説があります。

その他の資料

本講演とは関係ありませんが、PostgreSQL 12 の新機能説明資料でまとまっており、最近発行されたものを紹介いたします。

PostgreSQL 12 新機能検証結果 (Beta 1)(著者:日本HP 篠田 典良 さん)

PostgreSQL 12 新機能解説(著者:SRA OSS 近藤 雄太 さん)