Copyright©2019 NTT corp. All Rights Reserved.
PostgreSQL 12は ここがスゴイ!
~性能改善やpluggable storage engineなどの新機能を徹底解説~
澤田 雅彦
NTT OSSセンタ
NTTデータ テクノロジーカンファレンス 2019 (2019/9/5)
Copyright©2019 NTT corp. All Rights Reserved.
2018/7/1 開発開始
2019/4/1 Feature Freeze
2019/5/23 Beta 1
2019/6/20 Beta 2
2019/8/8 Beta 3
2019/9/X RC?
2019/10/X GA?
12のリリースと同時に9.4の
コミュニティサポートが終わることに注意
2
PostgreSQL 12
Copyright©2019 NTT corp. All Rights Reserved.
既存機能の大幅な改善や、
将来の機能拡張への基盤、
かゆい所に手が届くような機能が揃っている、
PostgreSQLの総合力が上がったバージョン。
ただ非互換に注意!
3
PostgreSQL 12はどんなバージョン?
Copyright©2019 NTT corp. All Rights Reserved.
約180個の新機能
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• Generated Columns(生成列)
• 非互換
4
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
5
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
PostgreSQL 12でもテーブル・パーティショニングの改善は多い(全体の約
15%、PG11もほぼ同じ)
新機能一覧
• パーティション・プルーニングの性能改善
• パーティション・テーブルへの外部キー制約の実現
• パーティション・テーブルへのCOPYの性能改善
• ATTACH PARTITIONのロックが弱くなった
– UPDATE/DELETE/INSERTと競合しなくなった
• pg_partition_root(), pg_partition_ancestors()
• パーティション境界に式を指定(テーブル作成時に評価)
6
テーブル・パーティショニングの改善
Copyright©2019 NTT corp. All Rights Reserved. 7
プランニング時間
PostgreSQL11の新機能紹介より
PostgreSQL10に
比べて早くなっている。
けど、まだプラン生成
時間が子テーブル数に
比例して伸びている
Copyright©2019 NTT corp. All Rights Reserved.
• これまでは、プランナは内部で使用するテーブルの管理情報(RangeTblEntry,
RelOptInfo)を全ての子テーブルについて作成してた。
• PG12では、プルーニング情報を求めた後に興味のある子テーブルだけの管理情
報を作成するようにした。
• 数千規模の子テーブルがある場合に有用
8
子テーブルが多い時のプラン生成時間が大幅に改善
0
20
40
60
80
100
120
50 100 500 1000 2000 5000 10000
実行計画作成時間(MS)
子テーブル数
プラン生成時間(Range Partitioning)
PG12 PG11 PG10
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
9
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
• WITH句で指定したクエリ結果を一時テーブルみたいな形で扱うことがで
きる
– 複雑なSQLをより単純な部品に分解することで、SQLを読みやすくできる
• 再帰SQLのときにも使う
• PostgreSQLの実装では常にCTEの結果を一時テーブルとして持つ
– work_memを使用
– クエリの意味は同じでもsubselectを使った時とは実行計画を異なる
• MySQLも8.0からサポート
10
Common Table Expression (CTE)
Copyright©2019 NTT corp. All Rights Reserved.
-- CTEを利用(PG11まで)
=# EXPLAIN
WITH test AS (SELECT * FROM a WHERE c = 1)
SELECT * FROM test WHERE d = 1;
QUERY PLAN
------------------------------------------------------------------------
CTE Scan on test (cost=8.17..8.20 rows=1 width=8)
Filter: (d = 1)
CTE test
-> Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8)
Index Cond: (c = 1)
(5 rows)
11
CTEとSubSelect - PostgreSQL 11まで -
-- SubSelectを利用
=# EXPLAIN
SELECT * FROM (SELECT * FROM a WHERE c = 1 and d = 1) as test;
QUERY PLAN
----------------------------------------------------------------
Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8)
Index Cond: (c = 1)
Filter: (d = 1)
(3 rows)
Copyright©2019 NTT corp. All Rights Reserved.
-- CTEを利用(PG12)
=# EXPLAIN
WITH test AS (SELECT * FROM a WHERE c = 1)
SELECT * FROM test WHERE d = 1;
QUERY PLAN
----------------------------------------------------------------------------------
Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8)
Index Cond: (c = 1)
Filter: (d = 1)
(3 rows)
12
CTEとSubSelect - PostgreSQL 12から -
-- SubSelectを利用
=# EXPLAIN
SELECT * FROM (SELECT * FROM a WHERE c = 1 and d = 1) as test;
QUERY PLAN
----------------------------------------------------------------
Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8)
Index Cond: (c = 1)
Filter: (d = 1)
(3 rows)
Copyright©2019 NTT corp. All Rights Reserved.
• デフォルトでCTEのクエリを展開するようになった(CTE inlining)
– 他のRDBMSもこっちの動作がデフォルトになっている
– ただし再帰SQL、SELECT以外、volatile関数が入っている場合は強制的に
MATERIALIZE(一時テーブル的な扱い)される
• [ NOT ] MATERIALIZED句で動作を制御可能
13
PostgreSQL 12以降のCTE
=# EXPLAIN
WITH test AS MATERIALIZED (SELECT * FROM a WHERE c = 1)
SELECT * FROM test WHERE d = 1;
QUERY PLAN
------------------------------------------------------------------------
CTE Scan on test (cost=8.17..8.20 rows=1 width=8)
Filter: (d = 1)
CTE test
-> Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8)
Index Cond: (c = 1)
(5 rows)
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
14
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
• テーブルのスキャン、VACUUMは最適化済み
• インデックスのVACUUM、末尾の切り詰めは依然時間がかかる
• INDEX_CLEANUP、TRUNCATEでVACUUM処理の細かい制御が可能
– (テーブルの特性に応じて)時間がかかる処理をスキップできるようになった
Vacuumの改善
テーブル
スキャン
インデックス
VACUUM
テーブル
VACUUM
末尾の
切り詰め
長時間化に注意
1行でもゴミがあれば、
インデックスをフルスキャン
長時間化に注意
共有バッファをフルスキャン
Visibility Mapで
ゴミがあるページ
のみをスキャン
15
ゴミがあるページ
のみをVACUUM
Copyright©2019 NTT corp. All Rights Reserved.
• SKIP_LOCKED [ boolean ]
– すでにロックされているテーブルをスキップする
• TRUNCATE [ boolean ]
– テーブルの切り詰めを行わない
– 共有バッファのフルスキャンを回避
– テーブル毎に設定可能
• INDEX_CLEANUP [ boolean ]
– インデックスのVACUUMを行わない
– インデックスのVACUUMは常にフルスキャン
– テーブル毎に設定可能
16
Vacuumの改善 - 新オプション -
Copyright©2019 NTT corp. All Rights Reserved.
• TRUNCATEオプション
– テーブルの物理サイズが小さくならない
– こういう時に「TRUNCATE false」を検討する
• 高頻度で更新されるテーブル(一括削除とかがない=末尾の切り詰めが期待できない)
• 共有バッファが大きい(数百GB)
• ホットスタンバイでの競合を避けたい
• INDEX_CLEANUPオプション
– インデックスが肥大化する可能性がある
• インデックスはテーブルよりも肥大化しにくい
• REINDEX CONCURRENTLYでオンラインでShrinkすることも可能
– こういう時に「INDEX_CLEANUP false」を検討する
• 大規模テーブルで頻繁に更新がかかる
• 定期的にREINDEXできる時間がある
17
注意点と使い所
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
18
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
• 他の列情報から計算式によって値を生成する列
• PG 12ではSTOREDのみ対応
– VIRTUALは未対応
• テーブル定義時に列に計算式を指定
• 行の書き込み時に計算式から算出されたデータが列に格納さ
れる
19
Generated Columns(生成列)
Copyright©2019 NTT corp. All Rights Reserved.
=# CREATE TABLE people (
height_m numeric,
weight_kg numeric,
bmi numeric
GENERATED ALWAYS AS
(weight_kg / pow(height_m, 2)) STORED
);
=# INSERT INTO people VALUES (1.7, 65);
=# SELECT * FROM people;
height_m | weight_kg | bmi
----------+-----------+---------------------
1.7 | 65 | 22.4913494809688581
(1 row)
=# UPDATE people SET weight_kg = 60;
=# SELECT * FROM people ;
height_m | weight_kg | bmi
----------+-----------+---------------------
1.8 | 60 | 20.7612456747404844
(1 row)
20
Generated Columns(生成列)
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
21
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
• XpathのJSON版
• SQL 2016
• JSONデータから特定の部分を指定し、抽出するための構文
(言語)
• jsonb型のデータに対してのみ利用可能
– json型は非対応
• jsonb_path_exists(target jsonb, path jsonpath)
• jsonb_path_match(target jsonb, path jsonpath)
• jsonb_path_query(target jsonb, path jsonpath)
• jsonb_path_query_array(target jsonb, path jsonpath)
• jsonb_path_query_first(target jsonb, path jsonpath)
22
SQL/JSON path
Copyright©2019 NTT corp. All Rights Reserved.
{
“data1”: {
“a”: [1,2,3],
“b”: {
“c”: “cc”
}
},
“data2”: “d”
}
23
‘$.data1’
jsonb_path_query
------------------------------------
{"a": [1, 2, 3], "b": {"c": "cc"}}
(1 row)
Copyright©2019 NTT corp. All Rights Reserved.
{
“data1”: {
“a”: [1,2,3],
“b”: {
“c”: “cc”
}
},
“data2”: “d”
}
24
‘$.data1.a’
jsonb_path_query
------------------
[1, 2, 3]
(1 row)
Copyright©2019 NTT corp. All Rights Reserved.
{
“data1”: {
“a”: [1,2,3],
“b”: {
“c”: “cc”
}
},
“data2”: “d”
}
25
‘$.data1.a[1]’
jsonb_path_query
------------------
2
(1 row)
Copyright©2019 NTT corp. All Rights Reserved.
{
“data1”: {
“a”: [1,2,3],
“b”: {
“c”: “cc”
}
},
“data2”: “d”
}
26
‘$.data1.a[*]’
jsonb_path_query
------------------
1
2
3
(3 rows)
Copyright©2019 NTT corp. All Rights Reserved.
{
“data1”: {
“a”: [1,2,3],
“b”: {
“c”: “cc”
}
},
“data2”: “d”
}
27
‘$.data1.a ? (@ % 2 == 0)’
jsonb_path_query
------------------
2
(1 row)
Copyright©2019 NTT corp. All Rights Reserved.
{
“data1”: {
“a”: [1,2,3],
“b”: {
“c”: “cc”
}
},
“data2”: “d”
}
28
‘$.data1.keyvalue()
jsonb_path_query
----------------------------------------------
{"id": 32, "key": "a", "value": [1, 2, 3]}
{"id": 32, "key": "b", "value": {"c": "cc"}}
(2 rows)
Copyright©2019 NTT corp. All Rights Reserved.
https://www.postgresql.org/docs/12/functions-json.html
29
JSON/PATHの演算子と関数
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
30
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
(例)
コインとサイコロを投げ、コインが裏で3の目が出る確率は?
コインを投げる事と、サイコロを投げる事は独立な事象と考えるこ
とができる。(コインの表裏によってサイコロの出る目の確率は変わらない)
P(A) = 1/2
P(B) = 1/6
P (A∩B) = P(A)P(B) = 1/2 * 1/6 = 1/12
31
行数見積もりの問題 - 事象の独立性 -
事象の独立性
P(A∩B) = P(A)P(B)
PostgreSQLでは、(問い合わせ結果の)行数を推定する際に、
列の値の独立性を仮定している
Copyright©2019 NTT corp. All Rights Reserved.
次のテーブルを考えてみる
• 住所テーブル
• 都道府県、市町村などが入っている
32
行数見積もりの問題
=# SELECT * FROM addresses;
prefecture | city | town | chome
------------+------+------+-----------------------------
東京都 | 港区 | 港南 |
東京都 | 港区 | 港南 |
東京都 | 港区 | 港南 | 品川インターシティA棟
東京都 | 港区 | 港南 | 品川インターシティA棟 1階
東京都 | 港区 | 港南 | 品川インターシティA棟 2階
東京都 | 港区 | 港南 | 品川インターシティA棟 3階
東京都 | 港区 | 港南 | 品川インターシティA棟 4階
東京都 | 港区 | 港南 | 品川インターシティA棟 5階
東京都 | 港区 | 港南 | 品川インターシティA棟 6階
東京都 | 港区 | 港南 | 品川インターシティA棟 7階
(10 rows)
Copyright©2019 NTT corp. All Rights Reserved. 33
行数見積もりの問題
QUERY PLAN
----------------------------------------------------------------------------------------
Seq Scan on addresses (cost=0.00..3476.01 rows=75 width=54)
(actual time=9.343..33.347 rows=1257 loops=1)
Filter: ((prefecture = '東京都'::text) AND (city = '千代田区'::text))
Rows Removed by Filter: 148144
Planning Time: 0.146 ms
Execution Time: 33.456 ms
(5 rows)(5 rows)
WHERE
prefecture = ‘東京都’
AND
city = ‘千代田区’
を考える。都道府県と市町村には相関がある。
(東京都の行には千代田区が出やすい)
見積値 75件に対し、
実際には1257件取得。
約16倍、行数見積が間違っている
Copyright©2019 NTT corp. All Rights Reserved.
PostgreSQLは各条件を独立の事象だとみなし見積を行っている
ため、結果行数を過小に見積もってしまった。
S(A)をAの選択率(Selectivity)とした時、
S(東京都) = 5.7%
S(千代田区) = 0.8%
S(東京都 ∩ 千代田区) = S(東京都)S(千代田区) = 5.7% * 0.8% = 0.05%
行数見積 = 全行数 * 選択率 = 149401 * 0.0005 ≒ 75
34
行数見積もりのズレ
P (A∩B) =
P(A)P(B)
Copyright©2019 NTT corp. All Rights Reserved.
• 相関関係のある複数列に跨った統計情報を作成できる
– 例) “都道府県”列と”市町村”列の値の組み合わせに対して統計情報を作
成する
• PostgreSQL 10で導入された機能
– Oracle Databaseには昔からある
• 複数条件に対する行数見積をより正確に行うことができる
• 作成できる統計情報
– ndistinct
– dependencies
– mcv (most common variables:最頻値)
35
CREATE STATISTICS(拡張統計情報)
Copyright©2019 NTT corp. All Rights Reserved. 36
拡張統計情報を使ってみる
=# CREATE STATISTICS stts ON prefecture, city FROM addresses;
CREATE STATISTICS
=# ANALYZE stts; --ANALYZE時に拡張統計情報が作成される
ANALYZE
=# EXPLAIN ANALYZE SELECT * FROM addresses
WHERE prefecture = '東京都‘ AND city = '千代田区';
QUERY PLAN
-------------------------------------------------------------------------------------
Seq Scan on addresses (cost=0.00..3476.01 rows=1290 width=54)
(actual time=10.958..37.468 rows=1257 loops=1)
Filter: ((prefecture = '東京都'::text) AND (city = '千代田区'::text))
Rows Removed by Filter: 148144
Planning Time: 0.493 ms
Execution Time: 37.584 ms
(5 rows)
=# SELECT m.* FROM pg_statistic_ext JOIN pg_statistic_ext_data on (oid = stxoid),
pg_mcv_list_items(stxdmcv) m WHERE m.values = ARRAY['東京都', '千代田区'];
index | values | nulls | frequency | base_frequency
-------+-------------------+-------+----------------------+-----------------------
2 | {東京都,千代田区} | {f,f} | 0.008633333333333333 | 0.0005001577777777778
(1 row)
正確に結果行数の
見積りができている
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
37
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
• 独自のテーブル(Access Method)を定義、使用できるよう
なった
– インデックス(Index AM)は9.6から可能
• 夢が広がる機能
例えば
• OracleライクなUNDOベースのテーブル
• 列指向テーブル
• インメモリテーブル
• 他DBとの連携(RocksDB + PostgreSQLなど)
• 分散テーブル
38
Pluggable Storage Engine (Table AM)
Copyright©2019 NTT corp. All Rights Reserved.
https://www.pgcon.org/2019/schedule/attachments/559_pgcon-2019-transaction-logging.pdf
39
MySQLのStorage Engineとの違い
Copyright©2019 NTT corp. All Rights Reserved. 40
アーキテクチャ - これまで -
https://anarazel.de/talks/2018-10-25-pgconfeu-pluggable-storage/pluggable.pdf
Copyright©2019 NTT corp. All Rights Reserved. 41
アーキテクチャ - PG 12から -
https://anarazel.de/talks/2018-10-25-pgconfeu-pluggable-storage/pluggable.pdf
Copyright©2019 NTT corp. All Rights Reserved.
• 公式にサポートしているのはHeapのみ
• PostgreSQL 13では、なにか新しい種類のTable AMが入るか
もしれない
42
PostgreSQL 12ではAPIが切られただけ
Copyright©2019 NTT corp. All Rights Reserved.
• zheap (EnterpriseDB社)
– 行指向
– UNDOログ
– タプルヘッダが小さい
• ZedStore (Pivotal社)
– 列指向
– UNDOログ
– 圧縮
• In-memory table
43
どんなAccess Methodが今後入りそうか
Copyright©2019 NTT corp. All Rights Reserved.
• UNDOログを利用
– 古いタプルはすべてUNDO領域に退避
– Commitなら退避した古いタプルを消す、Rollbackならもとに戻す
• In-place update
• VACUUMがいらない
• タプルヘッダが従来のテーブルよりも小さい
– 25 bytes → 5 bytes
– MVCCに必要なデータはUNDOログにある
• ソースは公開されているので試してみるのもあり
– https://github.com/EnterpriseDB/zheap
44
zheap
Copyright©2019 NTT corp. All Rights Reserved.
目的は異なるが機能性は一部重複している
• 目的の違い
– FDWは外部データとの連携が目的(SQL/MEDの実装系)
– Table AMはPostgreSQLのストレージ層の切り出し
• 機能の違い
– FDWでは、実行計画の作成(外部サーバが担当する部分の切り出し等)、外
部サーバからのデータ取得を担当
• GetForeignPaths、GetForeignJoinPath, ExecForeignScanなど
– Table AMは、Executor⇔ストレージのI/Fのみ(今後変わる可能性あり)
• scan_getnextslot, index_fetch_begin, scan_bitmap_next_block, tuple_insert,
tuple_delete, scan_bitmapなど
– FDWではDDLに対応していない
45
Foreign Data Wrapperとの違い
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• Generated Columns(生成列)
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• 非互換
46
PostgreSQL 12の新機能
Copyright©2019 NTT corp. All Rights Reserved.
• WITH OIDSの廃止
• recovery.confの廃止
• recovery_target_XXXの重複指定禁止
47
影響が大きそうな非互換
Copyright©2019 NTT corp. All Rights Reserved.
対象者
CREATE TABLE ... WITH OIDSを使っている人
内容
• WITH OIDSが使えなくなった
• WITH OIDSがあるテーブルがあるとpg_upgradeが実行
できない
対処方法
• WITH OIDSを使わなくても良い設計を検討する
• ALTER TABLE ... SET WITHOUT OIDSでOIDSを取り除く
48
WITH OIDSの廃止
Copyright©2019 NTT corp. All Rights Reserved.
対象者
リカバリまたはレプリケーションをする人(= 全員)
内容
• recovery.confはなくなりpostgresql.confに統合された
• 代わりにrecovery.signalやstandby.signalファイルが必要
• recovery.confがあると起動しない
対処方法
• recovery.confに書いていたパラメータをpostgresql.confに書
くようにする
• リカバリ時はrecovery.signal、スタンバイ時はstandby.signal
を置くようにする
• recovery_target_XXXは設定ファイルに必ず一つになるよう
にすること
49
recovery.confの廃止
Copyright©2019 NTT corp. All Rights Reserved.
• SHOWコマンドでリカバリ関連の設定値が確認できる
• リカバリやスタンバイサーバの設定値をreloadで反映できる
– archive_cleanup_command
– promote_trigger_file
– recovery_end_command
– recovery_min_apply_delay
50
大きな非互換だけどその恩恵は大きい
Copyright©2019 NTT corp. All Rights Reserved.
• 新機能による恩恵とアップグレードのコストのトレードオフ
• これぞという機能があればアップグレードを検討
– 悩みをうまく解決してくれる機能があるかも
• もれなく運用ツールの修正コストが付いてくることに留意す
る
51
12へアップグレードするべき?
Copyright©2019 NTT corp. All Rights Reserved.
• テーブル・パーティショニングの改善
• CTE Inlining
• Vacuum改善
• SQL/JSON Path
• CREATE STATISTICS(拡張統計情報)
• Pluggable Storage Engine(Table AM)
• Generated Columns(生成列)
• 非互換
52
まとめ
Copyright©2019 NTT corp. All Rights Reserved.
Thank you

PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ (NTTデータ テクノロジーカンファレンス 2019講演資料)

  • 1.
    Copyright©2019 NTT corp.All Rights Reserved. PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ 澤田 雅彦 NTT OSSセンタ NTTデータ テクノロジーカンファレンス 2019 (2019/9/5)
  • 2.
    Copyright©2019 NTT corp.All Rights Reserved. 2018/7/1 開発開始 2019/4/1 Feature Freeze 2019/5/23 Beta 1 2019/6/20 Beta 2 2019/8/8 Beta 3 2019/9/X RC? 2019/10/X GA? 12のリリースと同時に9.4の コミュニティサポートが終わることに注意 2 PostgreSQL 12
  • 3.
    Copyright©2019 NTT corp.All Rights Reserved. 既存機能の大幅な改善や、 将来の機能拡張への基盤、 かゆい所に手が届くような機能が揃っている、 PostgreSQLの総合力が上がったバージョン。 ただ非互換に注意! 3 PostgreSQL 12はどんなバージョン?
  • 4.
    Copyright©2019 NTT corp.All Rights Reserved. 約180個の新機能 • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • Generated Columns(生成列) • 非互換 4 PostgreSQL 12の新機能
  • 5.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 5 PostgreSQL 12の新機能
  • 6.
    Copyright©2019 NTT corp.All Rights Reserved. PostgreSQL 12でもテーブル・パーティショニングの改善は多い(全体の約 15%、PG11もほぼ同じ) 新機能一覧 • パーティション・プルーニングの性能改善 • パーティション・テーブルへの外部キー制約の実現 • パーティション・テーブルへのCOPYの性能改善 • ATTACH PARTITIONのロックが弱くなった – UPDATE/DELETE/INSERTと競合しなくなった • pg_partition_root(), pg_partition_ancestors() • パーティション境界に式を指定(テーブル作成時に評価) 6 テーブル・パーティショニングの改善
  • 7.
    Copyright©2019 NTT corp.All Rights Reserved. 7 プランニング時間 PostgreSQL11の新機能紹介より PostgreSQL10に 比べて早くなっている。 けど、まだプラン生成 時間が子テーブル数に 比例して伸びている
  • 8.
    Copyright©2019 NTT corp.All Rights Reserved. • これまでは、プランナは内部で使用するテーブルの管理情報(RangeTblEntry, RelOptInfo)を全ての子テーブルについて作成してた。 • PG12では、プルーニング情報を求めた後に興味のある子テーブルだけの管理情 報を作成するようにした。 • 数千規模の子テーブルがある場合に有用 8 子テーブルが多い時のプラン生成時間が大幅に改善 0 20 40 60 80 100 120 50 100 500 1000 2000 5000 10000 実行計画作成時間(MS) 子テーブル数 プラン生成時間(Range Partitioning) PG12 PG11 PG10
  • 9.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 9 PostgreSQL 12の新機能
  • 10.
    Copyright©2019 NTT corp.All Rights Reserved. • WITH句で指定したクエリ結果を一時テーブルみたいな形で扱うことがで きる – 複雑なSQLをより単純な部品に分解することで、SQLを読みやすくできる • 再帰SQLのときにも使う • PostgreSQLの実装では常にCTEの結果を一時テーブルとして持つ – work_memを使用 – クエリの意味は同じでもsubselectを使った時とは実行計画を異なる • MySQLも8.0からサポート 10 Common Table Expression (CTE)
  • 11.
    Copyright©2019 NTT corp.All Rights Reserved. -- CTEを利用(PG11まで) =# EXPLAIN WITH test AS (SELECT * FROM a WHERE c = 1) SELECT * FROM test WHERE d = 1; QUERY PLAN ------------------------------------------------------------------------ CTE Scan on test (cost=8.17..8.20 rows=1 width=8) Filter: (d = 1) CTE test -> Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8) Index Cond: (c = 1) (5 rows) 11 CTEとSubSelect - PostgreSQL 11まで - -- SubSelectを利用 =# EXPLAIN SELECT * FROM (SELECT * FROM a WHERE c = 1 and d = 1) as test; QUERY PLAN ---------------------------------------------------------------- Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8) Index Cond: (c = 1) Filter: (d = 1) (3 rows)
  • 12.
    Copyright©2019 NTT corp.All Rights Reserved. -- CTEを利用(PG12) =# EXPLAIN WITH test AS (SELECT * FROM a WHERE c = 1) SELECT * FROM test WHERE d = 1; QUERY PLAN ---------------------------------------------------------------------------------- Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8) Index Cond: (c = 1) Filter: (d = 1) (3 rows) 12 CTEとSubSelect - PostgreSQL 12から - -- SubSelectを利用 =# EXPLAIN SELECT * FROM (SELECT * FROM a WHERE c = 1 and d = 1) as test; QUERY PLAN ---------------------------------------------------------------- Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8) Index Cond: (c = 1) Filter: (d = 1) (3 rows)
  • 13.
    Copyright©2019 NTT corp.All Rights Reserved. • デフォルトでCTEのクエリを展開するようになった(CTE inlining) – 他のRDBMSもこっちの動作がデフォルトになっている – ただし再帰SQL、SELECT以外、volatile関数が入っている場合は強制的に MATERIALIZE(一時テーブル的な扱い)される • [ NOT ] MATERIALIZED句で動作を制御可能 13 PostgreSQL 12以降のCTE =# EXPLAIN WITH test AS MATERIALIZED (SELECT * FROM a WHERE c = 1) SELECT * FROM test WHERE d = 1; QUERY PLAN ------------------------------------------------------------------------ CTE Scan on test (cost=8.17..8.20 rows=1 width=8) Filter: (d = 1) CTE test -> Index Scan using a_pkey on a (cost=0.15..8.17 rows=1 width=8) Index Cond: (c = 1) (5 rows)
  • 14.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 14 PostgreSQL 12の新機能
  • 15.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブルのスキャン、VACUUMは最適化済み • インデックスのVACUUM、末尾の切り詰めは依然時間がかかる • INDEX_CLEANUP、TRUNCATEでVACUUM処理の細かい制御が可能 – (テーブルの特性に応じて)時間がかかる処理をスキップできるようになった Vacuumの改善 テーブル スキャン インデックス VACUUM テーブル VACUUM 末尾の 切り詰め 長時間化に注意 1行でもゴミがあれば、 インデックスをフルスキャン 長時間化に注意 共有バッファをフルスキャン Visibility Mapで ゴミがあるページ のみをスキャン 15 ゴミがあるページ のみをVACUUM
  • 16.
    Copyright©2019 NTT corp.All Rights Reserved. • SKIP_LOCKED [ boolean ] – すでにロックされているテーブルをスキップする • TRUNCATE [ boolean ] – テーブルの切り詰めを行わない – 共有バッファのフルスキャンを回避 – テーブル毎に設定可能 • INDEX_CLEANUP [ boolean ] – インデックスのVACUUMを行わない – インデックスのVACUUMは常にフルスキャン – テーブル毎に設定可能 16 Vacuumの改善 - 新オプション -
  • 17.
    Copyright©2019 NTT corp.All Rights Reserved. • TRUNCATEオプション – テーブルの物理サイズが小さくならない – こういう時に「TRUNCATE false」を検討する • 高頻度で更新されるテーブル(一括削除とかがない=末尾の切り詰めが期待できない) • 共有バッファが大きい(数百GB) • ホットスタンバイでの競合を避けたい • INDEX_CLEANUPオプション – インデックスが肥大化する可能性がある • インデックスはテーブルよりも肥大化しにくい • REINDEX CONCURRENTLYでオンラインでShrinkすることも可能 – こういう時に「INDEX_CLEANUP false」を検討する • 大規模テーブルで頻繁に更新がかかる • 定期的にREINDEXできる時間がある 17 注意点と使い所
  • 18.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 18 PostgreSQL 12の新機能
  • 19.
    Copyright©2019 NTT corp.All Rights Reserved. • 他の列情報から計算式によって値を生成する列 • PG 12ではSTOREDのみ対応 – VIRTUALは未対応 • テーブル定義時に列に計算式を指定 • 行の書き込み時に計算式から算出されたデータが列に格納さ れる 19 Generated Columns(生成列)
  • 20.
    Copyright©2019 NTT corp.All Rights Reserved. =# CREATE TABLE people ( height_m numeric, weight_kg numeric, bmi numeric GENERATED ALWAYS AS (weight_kg / pow(height_m, 2)) STORED ); =# INSERT INTO people VALUES (1.7, 65); =# SELECT * FROM people; height_m | weight_kg | bmi ----------+-----------+--------------------- 1.7 | 65 | 22.4913494809688581 (1 row) =# UPDATE people SET weight_kg = 60; =# SELECT * FROM people ; height_m | weight_kg | bmi ----------+-----------+--------------------- 1.8 | 60 | 20.7612456747404844 (1 row) 20 Generated Columns(生成列)
  • 21.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 21 PostgreSQL 12の新機能
  • 22.
    Copyright©2019 NTT corp.All Rights Reserved. • XpathのJSON版 • SQL 2016 • JSONデータから特定の部分を指定し、抽出するための構文 (言語) • jsonb型のデータに対してのみ利用可能 – json型は非対応 • jsonb_path_exists(target jsonb, path jsonpath) • jsonb_path_match(target jsonb, path jsonpath) • jsonb_path_query(target jsonb, path jsonpath) • jsonb_path_query_array(target jsonb, path jsonpath) • jsonb_path_query_first(target jsonb, path jsonpath) 22 SQL/JSON path
  • 23.
    Copyright©2019 NTT corp.All Rights Reserved. { “data1”: { “a”: [1,2,3], “b”: { “c”: “cc” } }, “data2”: “d” } 23 ‘$.data1’ jsonb_path_query ------------------------------------ {"a": [1, 2, 3], "b": {"c": "cc"}} (1 row)
  • 24.
    Copyright©2019 NTT corp.All Rights Reserved. { “data1”: { “a”: [1,2,3], “b”: { “c”: “cc” } }, “data2”: “d” } 24 ‘$.data1.a’ jsonb_path_query ------------------ [1, 2, 3] (1 row)
  • 25.
    Copyright©2019 NTT corp.All Rights Reserved. { “data1”: { “a”: [1,2,3], “b”: { “c”: “cc” } }, “data2”: “d” } 25 ‘$.data1.a[1]’ jsonb_path_query ------------------ 2 (1 row)
  • 26.
    Copyright©2019 NTT corp.All Rights Reserved. { “data1”: { “a”: [1,2,3], “b”: { “c”: “cc” } }, “data2”: “d” } 26 ‘$.data1.a[*]’ jsonb_path_query ------------------ 1 2 3 (3 rows)
  • 27.
    Copyright©2019 NTT corp.All Rights Reserved. { “data1”: { “a”: [1,2,3], “b”: { “c”: “cc” } }, “data2”: “d” } 27 ‘$.data1.a ? (@ % 2 == 0)’ jsonb_path_query ------------------ 2 (1 row)
  • 28.
    Copyright©2019 NTT corp.All Rights Reserved. { “data1”: { “a”: [1,2,3], “b”: { “c”: “cc” } }, “data2”: “d” } 28 ‘$.data1.keyvalue() jsonb_path_query ---------------------------------------------- {"id": 32, "key": "a", "value": [1, 2, 3]} {"id": 32, "key": "b", "value": {"c": "cc"}} (2 rows)
  • 29.
    Copyright©2019 NTT corp.All Rights Reserved. https://www.postgresql.org/docs/12/functions-json.html 29 JSON/PATHの演算子と関数
  • 30.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 30 PostgreSQL 12の新機能
  • 31.
    Copyright©2019 NTT corp.All Rights Reserved. (例) コインとサイコロを投げ、コインが裏で3の目が出る確率は? コインを投げる事と、サイコロを投げる事は独立な事象と考えるこ とができる。(コインの表裏によってサイコロの出る目の確率は変わらない) P(A) = 1/2 P(B) = 1/6 P (A∩B) = P(A)P(B) = 1/2 * 1/6 = 1/12 31 行数見積もりの問題 - 事象の独立性 - 事象の独立性 P(A∩B) = P(A)P(B) PostgreSQLでは、(問い合わせ結果の)行数を推定する際に、 列の値の独立性を仮定している
  • 32.
    Copyright©2019 NTT corp.All Rights Reserved. 次のテーブルを考えてみる • 住所テーブル • 都道府県、市町村などが入っている 32 行数見積もりの問題 =# SELECT * FROM addresses; prefecture | city | town | chome ------------+------+------+----------------------------- 東京都 | 港区 | 港南 | 東京都 | 港区 | 港南 | 東京都 | 港区 | 港南 | 品川インターシティA棟 東京都 | 港区 | 港南 | 品川インターシティA棟 1階 東京都 | 港区 | 港南 | 品川インターシティA棟 2階 東京都 | 港区 | 港南 | 品川インターシティA棟 3階 東京都 | 港区 | 港南 | 品川インターシティA棟 4階 東京都 | 港区 | 港南 | 品川インターシティA棟 5階 東京都 | 港区 | 港南 | 品川インターシティA棟 6階 東京都 | 港区 | 港南 | 品川インターシティA棟 7階 (10 rows)
  • 33.
    Copyright©2019 NTT corp.All Rights Reserved. 33 行数見積もりの問題 QUERY PLAN ---------------------------------------------------------------------------------------- Seq Scan on addresses (cost=0.00..3476.01 rows=75 width=54) (actual time=9.343..33.347 rows=1257 loops=1) Filter: ((prefecture = '東京都'::text) AND (city = '千代田区'::text)) Rows Removed by Filter: 148144 Planning Time: 0.146 ms Execution Time: 33.456 ms (5 rows)(5 rows) WHERE prefecture = ‘東京都’ AND city = ‘千代田区’ を考える。都道府県と市町村には相関がある。 (東京都の行には千代田区が出やすい) 見積値 75件に対し、 実際には1257件取得。 約16倍、行数見積が間違っている
  • 34.
    Copyright©2019 NTT corp.All Rights Reserved. PostgreSQLは各条件を独立の事象だとみなし見積を行っている ため、結果行数を過小に見積もってしまった。 S(A)をAの選択率(Selectivity)とした時、 S(東京都) = 5.7% S(千代田区) = 0.8% S(東京都 ∩ 千代田区) = S(東京都)S(千代田区) = 5.7% * 0.8% = 0.05% 行数見積 = 全行数 * 選択率 = 149401 * 0.0005 ≒ 75 34 行数見積もりのズレ P (A∩B) = P(A)P(B)
  • 35.
    Copyright©2019 NTT corp.All Rights Reserved. • 相関関係のある複数列に跨った統計情報を作成できる – 例) “都道府県”列と”市町村”列の値の組み合わせに対して統計情報を作 成する • PostgreSQL 10で導入された機能 – Oracle Databaseには昔からある • 複数条件に対する行数見積をより正確に行うことができる • 作成できる統計情報 – ndistinct – dependencies – mcv (most common variables:最頻値) 35 CREATE STATISTICS(拡張統計情報)
  • 36.
    Copyright©2019 NTT corp.All Rights Reserved. 36 拡張統計情報を使ってみる =# CREATE STATISTICS stts ON prefecture, city FROM addresses; CREATE STATISTICS =# ANALYZE stts; --ANALYZE時に拡張統計情報が作成される ANALYZE =# EXPLAIN ANALYZE SELECT * FROM addresses WHERE prefecture = '東京都‘ AND city = '千代田区'; QUERY PLAN ------------------------------------------------------------------------------------- Seq Scan on addresses (cost=0.00..3476.01 rows=1290 width=54) (actual time=10.958..37.468 rows=1257 loops=1) Filter: ((prefecture = '東京都'::text) AND (city = '千代田区'::text)) Rows Removed by Filter: 148144 Planning Time: 0.493 ms Execution Time: 37.584 ms (5 rows) =# SELECT m.* FROM pg_statistic_ext JOIN pg_statistic_ext_data on (oid = stxoid), pg_mcv_list_items(stxdmcv) m WHERE m.values = ARRAY['東京都', '千代田区']; index | values | nulls | frequency | base_frequency -------+-------------------+-------+----------------------+----------------------- 2 | {東京都,千代田区} | {f,f} | 0.008633333333333333 | 0.0005001577777777778 (1 row) 正確に結果行数の 見積りができている
  • 37.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 37 PostgreSQL 12の新機能
  • 38.
    Copyright©2019 NTT corp.All Rights Reserved. • 独自のテーブル(Access Method)を定義、使用できるよう なった – インデックス(Index AM)は9.6から可能 • 夢が広がる機能 例えば • OracleライクなUNDOベースのテーブル • 列指向テーブル • インメモリテーブル • 他DBとの連携(RocksDB + PostgreSQLなど) • 分散テーブル 38 Pluggable Storage Engine (Table AM)
  • 39.
    Copyright©2019 NTT corp.All Rights Reserved. https://www.pgcon.org/2019/schedule/attachments/559_pgcon-2019-transaction-logging.pdf 39 MySQLのStorage Engineとの違い
  • 40.
    Copyright©2019 NTT corp.All Rights Reserved. 40 アーキテクチャ - これまで - https://anarazel.de/talks/2018-10-25-pgconfeu-pluggable-storage/pluggable.pdf
  • 41.
    Copyright©2019 NTT corp.All Rights Reserved. 41 アーキテクチャ - PG 12から - https://anarazel.de/talks/2018-10-25-pgconfeu-pluggable-storage/pluggable.pdf
  • 42.
    Copyright©2019 NTT corp.All Rights Reserved. • 公式にサポートしているのはHeapのみ • PostgreSQL 13では、なにか新しい種類のTable AMが入るか もしれない 42 PostgreSQL 12ではAPIが切られただけ
  • 43.
    Copyright©2019 NTT corp.All Rights Reserved. • zheap (EnterpriseDB社) – 行指向 – UNDOログ – タプルヘッダが小さい • ZedStore (Pivotal社) – 列指向 – UNDOログ – 圧縮 • In-memory table 43 どんなAccess Methodが今後入りそうか
  • 44.
    Copyright©2019 NTT corp.All Rights Reserved. • UNDOログを利用 – 古いタプルはすべてUNDO領域に退避 – Commitなら退避した古いタプルを消す、Rollbackならもとに戻す • In-place update • VACUUMがいらない • タプルヘッダが従来のテーブルよりも小さい – 25 bytes → 5 bytes – MVCCに必要なデータはUNDOログにある • ソースは公開されているので試してみるのもあり – https://github.com/EnterpriseDB/zheap 44 zheap
  • 45.
    Copyright©2019 NTT corp.All Rights Reserved. 目的は異なるが機能性は一部重複している • 目的の違い – FDWは外部データとの連携が目的(SQL/MEDの実装系) – Table AMはPostgreSQLのストレージ層の切り出し • 機能の違い – FDWでは、実行計画の作成(外部サーバが担当する部分の切り出し等)、外 部サーバからのデータ取得を担当 • GetForeignPaths、GetForeignJoinPath, ExecForeignScanなど – Table AMは、Executor⇔ストレージのI/Fのみ(今後変わる可能性あり) • scan_getnextslot, index_fetch_begin, scan_bitmap_next_block, tuple_insert, tuple_delete, scan_bitmapなど – FDWではDDLに対応していない 45 Foreign Data Wrapperとの違い
  • 46.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • Generated Columns(生成列) • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • 非互換 46 PostgreSQL 12の新機能
  • 47.
    Copyright©2019 NTT corp.All Rights Reserved. • WITH OIDSの廃止 • recovery.confの廃止 • recovery_target_XXXの重複指定禁止 47 影響が大きそうな非互換
  • 48.
    Copyright©2019 NTT corp.All Rights Reserved. 対象者 CREATE TABLE ... WITH OIDSを使っている人 内容 • WITH OIDSが使えなくなった • WITH OIDSがあるテーブルがあるとpg_upgradeが実行 できない 対処方法 • WITH OIDSを使わなくても良い設計を検討する • ALTER TABLE ... SET WITHOUT OIDSでOIDSを取り除く 48 WITH OIDSの廃止
  • 49.
    Copyright©2019 NTT corp.All Rights Reserved. 対象者 リカバリまたはレプリケーションをする人(= 全員) 内容 • recovery.confはなくなりpostgresql.confに統合された • 代わりにrecovery.signalやstandby.signalファイルが必要 • recovery.confがあると起動しない 対処方法 • recovery.confに書いていたパラメータをpostgresql.confに書 くようにする • リカバリ時はrecovery.signal、スタンバイ時はstandby.signal を置くようにする • recovery_target_XXXは設定ファイルに必ず一つになるよう にすること 49 recovery.confの廃止
  • 50.
    Copyright©2019 NTT corp.All Rights Reserved. • SHOWコマンドでリカバリ関連の設定値が確認できる • リカバリやスタンバイサーバの設定値をreloadで反映できる – archive_cleanup_command – promote_trigger_file – recovery_end_command – recovery_min_apply_delay 50 大きな非互換だけどその恩恵は大きい
  • 51.
    Copyright©2019 NTT corp.All Rights Reserved. • 新機能による恩恵とアップグレードのコストのトレードオフ • これぞという機能があればアップグレードを検討 – 悩みをうまく解決してくれる機能があるかも • もれなく運用ツールの修正コストが付いてくることに留意す る 51 12へアップグレードするべき?
  • 52.
    Copyright©2019 NTT corp.All Rights Reserved. • テーブル・パーティショニングの改善 • CTE Inlining • Vacuum改善 • SQL/JSON Path • CREATE STATISTICS(拡張統計情報) • Pluggable Storage Engine(Table AM) • Generated Columns(生成列) • 非互換 52 まとめ
  • 53.
    Copyright©2019 NTT corp.All Rights Reserved. Thank you