pgsql-hackersウォッチ(2026年10月)

今回は、PostgreSQL の開発者向けメーリングリストである pgsql-hackers で、2026年10月に行われた議論の中から、筆者が注目した話題を紹介します。網羅的なまとめではなく、筆者が追跡した範囲での内容となります。

10月は PostgreSQL 20 以降に向けた性能改善の議論が活発でした。インデックスの圧縮、高並列環境でのスケーラビリティ改善、クエリ最適化アルゴリズムなど、興味深いテーマが数多く議論されていました。

B-treeインデックスのプレフィックス圧縮

インデックスサイズの削減を目的として、B-tree インデックスに対するプレフィックス圧縮の提案がありました。

対象となるのは URL や JSON パス、逆DNS名など、多くの値が長い共通接頭辞(プレフィックス)を持つケースです。提案では、ページ単位で共通部分をまとめて保持し、各キーでは重複部分を省略することでサイズを削減します。

評価では、長い共通部分(https://www.example.com/… のようなURLの先頭部分)を持つURLデータの挿入テストでインデックスサイズが 3 分の 1 以下になったことが報告されています。一方で、B-tree 圧縮に関する SIGMOD 2024 の報告も引き合いに出され、検索時のCPUコストについて議論となりました。実際のオーバヘッドの確認や、それを削減できるケースの検討もされています。

並列ビットマップスキャンの改善

PostgreSQLでは、大量の行を検索するときに、複数のインデックス検索結果を組み合わせて対象となる行を絞り込むことがあります。この処理に使われるのがビットマップスキャン(Bitmap Scan)です。

現在のPostgreSQLでは、Bitmap Scanのうちテーブルから実際にデータを読み出す部分は並列化されていますが、インデックスを検索してビットマップを作成する部分は並列化されていません。今回、このインデックス検索も複数のプロセスで分担して実行する仕組みが提案されました。

各プロセスが並列にインデックスの一部を検索し、全ての結果が集まった後で、担当するテーブル部分の再割当てが行われ、並列にデータ読み出しを行います。 PoC としてパッチが投稿されましたが、その後も各プロセスへのメモリ割り当て方法や、B-tree 以外のインデックスの対応など、議論と開発が続いています。

スナップショットの再利用の高速化

高並列環境での性能改善として、スナップショット取得時のロックを減らす議論が進んでいます。

PostgreSQLでは、複数のトランザクションが同時に動作していても、一貫性のあるデータを参照できるようにMVCCという仕組みを採用しています。そのために使われるのがスナップショットで、ある時点でどのトランザクションの変更が見えるかを表しています。

現状では、スナップショット取得の際には内部でロックを取得するため、これが高並列環境でのボトルネックとなり、性能低下の原因となる場合があります。そこで、前回の取得以降に新たなコミットが発生していなければ、既存のスナップショットを再利用することで、ロックの取得を省略する仕組みが検討されています。

今月の議論では、スナップショットをまだ取得していない場合にも過去のスナップショットを再利用し、必要な情報はロックを使わずに更新する方法が検討されました。

OR条件をUNION ALLに展開する最適化

プランナ関連では、複数テーブルにまたがる OR 条件を UNION ALL に変換する最適化が提案されました。

複数テーブルにまたがる OR 条件(a.x = b.y OR a.x = b.z など)では、ハッシュ結合やマージ結合といった方法が使われず、性能が低下するという場合があります。これに対して、OR条件を複数の独立した検索に分解し、それらをUNION ALLで結合する形に変換する最適化の提案です。条件を分けることで、それぞれの検索に適した実行計画を選べるようになります。

提案のきっかけとなったのは、(残念ながら PostgreSQL 19 では見送りとなった)SQL/PGQ (グラフクエリ)機能です。グラフ探索の「無向エッジ」パターン検索では「A→B または B→A」といった OR 条件が現れますが、これを手動で UNION ALL で書き換えると数千倍の性能差が出た経験が元になっているようです。

書き換えの際には、重複した結果が出力されないように条件を追加する工夫も行われており、クエリ変換による最適化の面白さを感じる話題でした。

Quickselect による Top-N ソート

アルゴリズム面では、ORDER BY … LIMIT N を高速化するために Quickselect を利用する提案がありました。

ORDER BYとLIMITを組み合わせたSQLでは、全件をソートせずに、上位N件だけを効率よく取り出す処理(Top-N ソート)が重要になります。PostgreSQLでは、従来はこの処理にヒープを使った方法が使われていますが、LIMIT 値が大きい場合には効率が悪くなることがあります。

そこで提案されたのが、全体を並べ替えるのではなく、上位N件を選び出すQuickselectというアルゴリズムの利用です。まず上位N件に相当する範囲を選び出し、最後にそのN件だけをソートすることで計算量の削減を行っています。一方、メモリが不足する場合には従来のヒープソート方式に切り替えるなどの工夫も検討されています。

元々は SIMD を活用した別の研究成果(SIMDQuickHeap)を PostgreSQL に応用することを検討していたところ、Quickselect 単体でも十分な効果が期待できると判断しての提案であったようです。問題に適したアルゴリズムを選び直すという意味でも興味深い話題でした。

In-Placeメジャーバージョンアップグレード

運用面では、既存インスタンスを直接アップグレードする in-place アップグレードの提案が興味深い話題でした。

PostgreSQLのメジャーバージョンアップでは、通常pg_upgradeというツールが使われます。既存のデータを引き継ぎながら、新しいバージョンのデータベースを構築する仕組みですが、データベースインスタンスは新規に作成する必要があり、システムカタログの再作成やデータの移行には SQL 文のダンプとリストアを行うため、データベースの規模によっては時間がかかります。また、スタンバイサーバーは再構築する必要があります。

今回提案された pg_inplace_upgrade は、システムカタログを直接更新することで、既存のデータベースインスタンスをそのまま(in-placeで)アップグレード可能とするツールです。また、カタログの変更をWALに記録することで、スタンバイサーバーも作り直すことなくアップグレード可能です。

10月に PoC パッチが投稿され議論が始まりました。一方で、実装や保守の複雑化を懸念する意見もあり、活発な議論が行われています。

今回取り上げた話題は、性能改善やスケーラビリティ向上に関するものが中心となりました。特に、アルゴリズムやデータ構造、クエリ最適化に関する議論は、個々の機能だけでなく、その背景にある考え方に触れられる点も興味深く感じました。