Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

PostgreSQLにおけるパーティショニング性能向上 - PostgreSQL Confer...

Yuya Watari
December 06, 2024

PostgreSQLにおけるパーティショニング性能向上 - PostgreSQL Conference Japan 2024

Yuya Watari

December 06, 2024
Tweet

More Decks by Yuya Watari

Other Decks in Technology

Transcript

  1. 2 © 2024 NTT CORPORATION 自己紹介 名前  渡 佑也(わたり

    ゆうや) 所属  日本電信電話株式会社(NTT)オープンソースソフトウェアセンタ ソフトウェア技術サポートプロジェクト 基盤技術グループ  PostgreSQLのコミュニティ開発や分散データベースの研究開発に従事 興味  プランニング  分散トランザクション  写真
  2. 3 © 2024 NTT CORPORATION 概要 キーワード  パーティショニング •

    テーブルを物理的に小さなパーティションに分割する機能 トピック  パーティショニングされているときのプランニング性能を向上させる取り組み • 現在のPostgreSQLにはプランニング性能に課題がある  最大で22.5倍の高速化を実現  性能改善をPostgreSQLコミュニティに提案して議論中 パーティションテーブル パーティション パーティション パーティション
  3. 4 © 2024 NTT CORPORATION アジェンダ 1. パーティショニングの基本 2. パーティショニング性能の課題

    3. 性能改善の検証結果 4. コミュニティでの議論動向 5. まとめ
  4. 6 © 2024 NTT CORPORATION テーブルパーティショニング テーブルを物理的に小さなパーティションに分割する機能  大量のデータを扱わなければならない今日において 高いスケーラビリティと運用性を実現するうえで鍵となる

     例:ログデータの管理 継続的に発生するログデータを 日ごとにパーティションに分割して保持 論理的には一つの大きなテーブルとして 扱うことができる パーティションテーブル パーティション 2024年1月1日 パーティション 2024年1月2日 パーティション 2024年12月31日
  5. 7 © 2024 NTT CORPORATION パーティショニングの歴史 PostgreSQL 10において宣言的パーティショニングが導入された  構文レベルでサポートされ簡単に利用できるように

    • それまではテーブルの継承とCHECK制約により実現していた • 使いやすさが格段に向上したほか、性能も向上  例:パーティションテーブルの定義 CREATE TABLE t1(id INT, name TEXT) PARTITION BY RANGE (id); CREATE TABLE t1_1 PARTITION OF t1 FOR VALUES FROM (0) TO (100); CREATE TABLE t1_2 PARTITION OF t1 FOR VALUES FROM (100) TO (200); 親テーブルの定義 子パーティションの 定義 t1 t1_1 0 <= id < 100 t1_2 100 <= id < 200
  6. 8 © 2024 NTT CORPORATION パーティショニングの高速化 パーティション・プルーニング(PostgreSQL 10から)  クエリの結果に関係のないパーティションをプランから除外することで

    不要なアクセスを削減して実行速度を向上  例  PostgreSQL 11からは、実行時にしか分からない情報も活用して さらに高度なパーティション・プルーニングをするようになった SELECT * FROM t1 WHERE id < 100 t1 t1_1 0 <= id < 100 t1_2 100 <= id < 200 パーティションt1_2は結果に影響 しないためスキャンしなくてよい  プランから除外
  7. 9 © 2024 NTT CORPORATION パーティショニングの高速化(続き) パーティション・ワイズ結合/集約(PostgreSQL 11から)  PostgreSQL

    10でパーティションテーブルを結合・集約しようとすると 一度パーティションの内容をすべてまとめてから(Append)演算していた t1_1 0 <= id < 100 t1_2 100 <= id < 200 t2_1 0 <= id < 100 t2_2 100 <= id < 200 Append Append 結合演算 SELECT * FROM t1, t2 WHERE t1.id = t2.id
  8. 10 © 2024 NTT CORPORATION パーティショニングの高速化(続き) パーティション・ワイズ結合/集約(PostgreSQL 11から)  パーティション・ワイズ結合/集約では、パーティションが同じキーを持つ

    場合、対応するパーティション同士で演算を行った後にAppend • 先ほどのクエリは次の図のように実行できるようになり効率化 t1_1 0 <= id < 100 t2_1 0 <= id < 100 t1_2 100 <= id < 200 t2_2 100 <= id < 200 結合演算 結合演算 Append
  9. 12 © 2024 NTT CORPORATION プランニング性能の課題 場合によってはプランニングに長時間かかるという課題が存在する  クエリはPostgreSQL内部で実行計画に変換されてから実行される •

    これをプランニングと呼び、プランニングを行うモジュールをプランナという  プランニングは一瞬で終わると思われがちだが、時には無視できないほど長く かかることもある クエリ プランナ エグゼキュータ 結果 パーティション・プルーニングや パーティション・ワイズ結合/集約は エグゼキュータでの実行を高速化する技術 プランニングそのもののパフォーマンスにも課題が存在!
  10. 13 © 2024 NTT CORPORATION プランニングはどんなとき時間がかかるか パーティション数が多いときプランニング時間は増加する  冒頭のログデータを管理する例では、3年のデータに対して1000以上のパー ティションを持つ必要がある

     パーティション数が多いとプランニング時間が急激に増加する可能性がある パーティションテーブル パーティション 2022年1月1日 パーティション 2022年1月2日 パーティション 2022年1月3日 パーティション 2024年12月31日 1000個以上の大量の子パーティション
  11. 14 © 2024 NTT CORPORATION プランニング性能改善の取り組み これまでのバージョンアップでもプランニング性能の改善はなされてきた  パーティション・プルーニングはPostgreSQL 10で導入されたとき

    パーティション数が多いとプランニングに時間がかかる問題を抱えていた  PostgreSQL 11でこの問題が改善 次のプランニング性能改善は?  PostgreSQL 18向けに提案している最新の改善を紹介
  12. 15 © 2024 NTT CORPORATION 簡単なクエリで検証 3つのテーブルを結合するシンプルな例でプランニング時間を計測  クエリは次の通りシンプル 

    テーブルt1、t2、t3はパーティショニングされている  パーティション・ワイズ結合は無効化して検証 各テーブル(t1、t2、t3)が多数の子パーティションに分割されているときの プランニング時間(≒EXPLAINコマンドの実行時間)はどうなる? SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t1.id = t3.id
  13. 16 © 2024 NTT CORPORATION 簡単なクエリで検証 — 結果 各テーブルのパーティションの数が 多いとプランニング時間は大幅に増加

     1024パーティション存在するとき プランニング時間は0.3秒 • 環境によってはこれより長くかかる ことも • 十分体感できる程度の遅さとなる  さらに多くのパーティションが存在 する場合、プランニング時間は 急激に増加すると見込まれる 0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0 200 400 600 800 1000 プランニング時間(秒) 各テーブルのパーティション数 PostgreSQL 17 better
  14. 17 © 2024 NTT CORPORATION この問題が生じる条件 次の3つの条件を満たすときプランニング時間が大幅に増加する  決して珍しくないありがちなワークロード パーティションテーブル

    パーティション パーティション パーティションテーブル パーティション パーティション (2) 大量のパーティションを持つ (3) プルーニングが効きづらいため 大半がクエリに関与する かつ (1) 結合演算を含む
  15. 18 © 2024 NTT CORPORATION なぜこのような問題が生じるのか パーティション数が多いとき結合演算の等価性を管理する機構での処理が ボトルネックとなっている  先ほどのクエリには3つの結合順序が存在する

    • ここでは内部表と外部表の入れ替えは無視する  最後の結合条件「t2.id = t3.id」はクエリに出現しないため自明ではないが 結合演算の等価性を管理する機構により導出されている SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t1.id = t3.id t1 t2 t3 ⋈ ⋈ t1 t3 t2 ⋈ ⋈ t2 t3 t1 ⋈ ⋈ t1.id = t2.id t1.id = t3.id t1.id = t2.id t1.id = t2.id t1.id = t3.id t2.id = t3.id
  16. 19 © 2024 NTT CORPORATION 原因を特定して改善を提案 結合演算の等価性を管理する機構が持つデータ構造内の要素数が増えて探索に 時間がかかることが原因 この問題を解決する改善をコミュニティに提案 PostgreSQL

    18でのコミットを目指して議論中  問題に気付いたきっかけ • パーティション数が多い状況下でのパーティション・プルーニングなどの性能を調べ ていたが、異常にプランニングに時間がかかることに気づく • 問題の切り分けを行っていったところ、パーティション・プルーニングなどに関係な く、多数のパーティションを持つテーブル同士の結合演算であれば広く一般に起こる 問題であることを確認 • PostgreSQLのソースコードレベルでの調査により、結合演算の等価性を管理する機 構に直接的な問題個所を発見
  17. 21 © 2024 NTT CORPORATION 性能検証 プランニング時間改善の効果を確認する性能検証を実施 1. 3つのテーブルを結合するときのプランニング時間 •

    パーティション・ワイズ結合なし • 冒頭に示したグラフと同じ実験条件 2. 3つのテーブルを結合するときのプランニング時間 • パーティション・ワイズ結合あり • それ以外は1. と同じ 3. 結合するテーブル数を2個~6個に変化させたときのプランニング時間 4. Join Order Benchmarkにおけるプランニング時間
  18. 22 © 2024 NTT CORPORATION 検証1 3つのテーブルを結合するときのプランニング時間を計測(冒頭と同じ検証)  クエリは次の通りシンプル 

    テーブルt1、t2、t3はパーティショニングされている  パーティション・ワイズ結合は無効化して検証 SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t1.id = t3.id
  19. 23 © 2024 NTT CORPORATION 検証1 — 結果 プランニング時間が劇的に改善 

    1024パーティション存在するとき 6.9倍の高速化 • 0.3秒かかっていたものが 0.05秒以下に短縮  増加の仕方も二次関数的なものから 直線的なものになっている 0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0 200 400 600 800 1000 プランニング時間(秒) 各テーブルのパーティション数 PostgreSQL 17 改善後 6.9倍の 高速化 better
  20. 24 © 2024 NTT CORPORATION 0 0.1 0.2 0.3 0.4

    0.5 0.6 PostgreSQL 17 改善後 PostgreSQL 17 改善後 パーティション・ワイズ結合 なし パーティション・ワイズ結合 あり プランニング時間(秒) 各テーブルのパーティション数が1024のとき 検証2 同様の検証をパーティション・ ワイズ結合ありでも実施  各テーブルのパーティション数は 1024に固定 高い性能改善を確認 6.9倍の 高速化 2.6倍の 高速化 better
  21. 25 © 2024 NTT CORPORATION 検証3 結合するテーブル数を2個~6個に変化させたときのプランニング時間を計測  クエリは次の通り 

    パーティション・ワイズ結合は無効化して検証 SELECT * FROM t1, t2, …, tm WHERE t1.id = t2.id … AND t1.id = tm.id 結合するテーブル数を変化させる
  22. 26 © 2024 NTT CORPORATION 多くのテーブルを結合するほど 高い効果を示した  6つのテーブルを結合する場合 5.5秒が0.2秒まで短縮

    • 22.5倍の大幅な高速化 2 3 4 5 6 PostgreSQL 17 0.06 0.30 1.12 2.70 5.50 改善後 0.02 0.04 0.08 0.14 0.24 0 1 2 3 4 5 6 プランニング時間(秒) 結合するテーブル数 各テーブルのパーティション数が1024のとき PostgreSQL 17 改善後 検証3 — 結果 2.9倍 6.9倍 14.1倍 19.0倍 22.5倍 better
  23. 27 © 2024 NTT CORPORATION 検証4 Join Order Benchmarkにおいても高い性能向上を実現 

    Join Order Benchmark • OLAPのワークロードを評価する有名なベンチマーク  1024パーティション存在する状況でプランニング時間の高速化率を計測 0 5 10 15 20 25 高速化率 クエリ 1 平均で14.2倍の 高速化 最大で22.3倍の高速化 better
  24. 30 © 2024 NTT CORPORATION 今年の5月にカナダ・バンクーバーで開催されたPostgreSQL開発者向けの 国際会議「PGConf.dev 2024」にて本取り組みを紹介  本改善の詳細な実装デザインや

    検証結果を紹介し有用性を アピール  コミッターやパッチの レビュアーの方とも議論 PGConf.dev 2024で講演 講演の様子 主催者公開の動画より(https://youtu.be/TapL9PRvNLM)
  25. 32 © 2024 NTT CORPORATION まとめ  テーブルパーティショニングは大量のデータを扱わなければならない今日にお いて非常に重要な機能 

    PostgreSQLには多数のパーティションが存在するテーブルを結合しようと したときプランニングに非常に長い時間がかかるという問題が存在  結合演算の等価性を管理する機構が原因  この問題を改善してPostgreSQLコミュニティに提案中  改善によって最大で22.5倍の高速化が実現
  26. 33 © 2024 NTT CORPORATION 参考文献 本改善の議論やソースコードは次の場所から参照可能  https://commitfest.postgresql.org/50/3701/ 

    https://github.com/postgresql-cfbot/postgresql/tree/cf/3701  https://www.postgresql.org/message-id/flat/CAJ2pMkZNCgoUKSE+_5LthD+Kb [email protected] Join Order Benchmark  Leis, Viktor, et al. "How good are query optimizers, really?." Proceedings of the VLDB Endowment 9.3 (2015): 204-215.  https://github.com/winkyao/join-order-benchmark