本記事は、調査・実測・執筆のほぼ全量を Anthropic の AI モデル Claude(Fable 5)が行っています。筆者は調査の指示、構成と内容のレビュー、実測環境の提供、公開判断を担当しました。
レビュー足りてないところがありましたら、是非コメント等頂ければ幸いです。
2025 年 6 月に公開された こばさんの「pg_duckdbとDuckLakeがもたらすOLAP統合の未来」1は、pg_duckdb と DuckLake を軸に「PostgreSQL をインターフェースとしたワンストップな分析ツールセット」という未来を描いた記事でした。あれから 1 年、この分野は買収と新製品で大きく動いています。本記事は、Claude の新モデル Fable 5 が使えるうちに、「あの記事が描いた未来は 2026 年 7 月時点でどこまで来たか」を調査・実測してまとめてもらった、現時点版のスナップショットです。
調査にあたって Fable 5 は、こばさんの記事が深掘りした pg_duckdb と DuckLake だけを追うのではなく、この 1 年で一気に増えたマネージド型や zero-ETL 型まで、「PostgreSQL で OLTP(業務トランザクション処理)と OLAP(集計・分析処理)を両立する」選択肢の全体に範囲を広げました。そのままでは製品名の羅列になるため、「列指向のデータと実行エンジンをどこに置くか」という軸で 4 つに分類し、その軸が本当に性能を左右するのかを、起点の記事の主役である pg_duckdb と、展望の到達点として登場していた pg_ducklake の実測で確かめる、という組み立てにしています。過去記事で実測した ClickHouse の Managed Postgres2、AlloyDB の列指向エンジン3、Databricks Lakebase4 も判断材料に組み込みました。
結論を先に書きます。
- PostgreSQL で OLTP と OLAP を両立する選択肢は、列指向のデータと実行エンジンをどこに置くかで 4 つに分類できる
- 主要 12 製品を 6 観点で比較した。根拠は公式ドキュメントと過去の実測記事で裏取りした
- pg_duckdb を 4,327万件で実測したところ、PostgreSQL のテーブルを直接読む使い方では単純集計が素の PostgreSQL より遅く(0.43 倍)、同じデータを Parquet に変換すると 17〜32 倍になった
- こばさんの記事の展望どおりの名前で登場した pg_ducklake(DuckLake テーブル)も実測した。同じ 2 クエリで 16〜34 倍、heap からの 4,327万行の投入は約 10 秒だった
- 過去記事で実測した AlloyDB(11.6 倍)、ClickHouse(約 18 倍)と同じデータ・同じクエリの相対比を並べると、性能を大きく左右するのは製品名ではなく列データの置き場だと分かる
想定読者は「PostgreSQL で OLTP を運用していて、集計・分析クエリが重くなってきた」人です。提供状況やステータスは 2026 年 7 月時点のものです。
1. はじめに:なぜ今 PostgreSQL で OLTP と OLAP なのか
OLTP の正データを PostgreSQL に置く構成は広く使われていますが、行指向の PostgreSQL は大量データの集計が苦手です。実際、後述の実測では 14 列のうち 1 列しか使わない集計でも、テーブル全体の約 5.5 GB を読みます。
一方で 2025 年から 2026 年にかけて、この分野では大きな動きが続きました。Snowflake が Crunchy Data を買収して Snowflake Postgres を GA にし5、Databricks は Neon に続いて Mooncake Labs を買収して Lakebase を進め6、ClickHouse は Managed Postgres を出しました7。OSS 側でも pg_duckdb が v1.0 を越え8、Snowflake は pg_lake をオープンソースにしています9。「PostgreSQL を分析にどう広げるか」への答えが、短期間に集中して出てきた分野です。
本記事では、この選択肢を分類して比較し、分類の軸そのものを pg_duckdb と pg_ducklake の実測で確かめます。
2. 全体像:4 つの方式
分析を速くするには、どこかに列指向のデータ(またはキャッシュ)と、それを読む実行エンジンが必要です。それを「どこに置くか」で、主要な選択肢は次の 4 つに分かれます(図と表では PostgreSQL を PG と略すことがあります)。図の矢印は、列データ(またはキャッシュ)の置き場を表します。
| 分類 | 考え方 | 製品(提供状況) |
|---|---|---|
| ① エンジン内蔵型 | 同じ PostgreSQL の中に列指向のストレージや実行エンジンを足す | AlloyDB columnar engine(GA)、pg_duckdb(v1.1.1)、TimescaleDB Hypercore(Community 版)、Citus columnar(v14.1) |
| ② レイクハウス連携型 | PostgreSQL を Iceberg / Parquet などデータレイクの窓口にする | pg_lake(Apache 2.0、2025 年 11 月に OSS 化)、pg_mooncake(v0.x プレビュー)、pg_ducklake(2026 年 6 月に v1.0.0) |
| ③ マネージドセット型 | OLTP 用の PostgreSQL と分析エンジンをベンダーがセットで提供する | ClickHouse Managed Postgres(Beta)、Databricks Lakebase(Autoscaling / Provisioned)、Snowflake Postgres(2026 年 2 月 GA) |
| ④ zero-ETL・ミラーリング型 | PostgreSQL には手を入れず、クラウドの分析基盤へ自動複製する | Aurora PostgreSQL zero-ETL(Redshift へ)、Azure Database for PostgreSQL の Fabric ミラーリング(GA) |
このほか、ParadeDB は分析用拡張 pg_analytics を 2025 年 3 月にアーカイブして全文検索の pg_search に集約したため10、今回の比較からは外しました。Hydra は pg_duckdb の共同開発側に回っています8。PostgreSQL 互換の別エンジン(CedarDB など)や、DuckDB 側から PostgreSQL を読む方向の話も、今回は対象外です。
3. 6 観点で比べる
読者が選ぶときに判断が分かれるのは、次の 6 観点だと考えて整理しました。
- 提供形態:OSS 拡張か、マネージドか。ライセンス
- 列指向実行の場所:同一プロセスか、別プロセスか、別サービスか
- データの新しさ:同じデータを直接読むか、複製までの遅れがあるか
- 書き込み整合性:分析側の読み取りがトランザクションと一貫か、結果整合か
- 運用の重さ:拡張を入れるだけか、別基盤の運用が増えるか
- 無料で試せるか:セルフホスト・無料枠・トライアルの有無
3.1. ① エンジン内蔵型
| 製品 | 提供形態 | 実行の場所 | データの新しさ | 書き込み整合性 | 運用の重さ | 無料で試せるか |
|---|---|---|---|---|---|---|
| AlloyDB columnar engine | Google Cloud マネージド(Omni はセルフホスト可)11 | 同一インスタンス内。選んだ列をメモリ上の列キャッシュに保持 | 行ストアが正。頻繁な更新は列キャッシュを無効化し、設定した頻度で再構築 | 公式に明文なし(無効化ブロックの監視メトリクスあり) | フラグ有効化と再起動のみ | 無料トライアルクラスタあり |
| pg_duckdb | OSS 拡張(MIT)8 | 同一プロセスに DuckDB を組み込み | PG テーブルを直接読むため遅れなし | 同一トランザクションで PG と DuckDB 両テーブルへの書き込みは不可12 | 拡張のインストールのみ | OSS。公式 Docker イメージあり |
| TimescaleDB Hypercore | OSS 拡張。ただし columnstore は Community 版(TSL)のみで Apache-2 版には無い13 | 同一テーブル内。新しいデータは行ストア、古いチャンクは自動で列ストアへ変換14 | 同一テーブルで完結するため遅れなし | 列ストアにも INSERT / UPDATE / DELETE 可、ACID サポートを明記 | 拡張+変換ポリシー設定 | セルフホスト無料(DBaaS としての再販は不可) |
| Citus columnar | OSS 拡張(AGPL-3.0)15 | 同一プロセス。USING columnar でテーブル自体を列指向に |
テーブルそのものが列指向のため遅れなし | columnar テーブルは UPDATE / DELETE 非対応。バッチロード前提 | 拡張のインストールのみ | OSS |
①の中でも設計は分かれています。AlloyDB は「行ストアが正、列はキャッシュ」、Citus は「テーブルごと列指向」、TimescaleDB は「新しい行は行ストア、古い行は列ストア」、pg_duckdb は「データは行のまま、実行エンジンだけ列指向」です。この違いが 4 章の実測に直結します。
3.2. ② レイクハウス連携型
| 製品 | 提供形態 | 実行の場所 | データの新しさ | 書き込み整合性 | 運用の重さ | 無料で試せるか |
|---|---|---|---|---|---|---|
| pg_lake | OSS 拡張群(Apache 2.0)。Crunchy Data 由来で Snowflake が OSS 化169 | 別プロセス。クエリの一部を pgduck_server(DuckDB 内蔵の独立プロセス)で実行 | heap・Iceberg・外部 Parquet/CSV を同じ SQL で直接読み書き | PostgreSQL のトランザクションの仕組みのまま Iceberg を作成・更新できると明記 | 拡張に加えて pgduck_server と S3 相当のオブジェクトストレージが必要 | OSS。Docker で試せる |
| pg_mooncake | OSS 拡張(MIT)。開発元 Mooncake Labs は 2025 年 10 月に Databricks へ176 | 同一プロセス(pg_duckdb を統合)。列ストアは Iceberg 形式のミラー | moonlink によるリアルタイム取り込み(具体的な遅延の公式数値なし) | 公式に明文なし(非同期ミラーのため結果整合とみられる) | 拡張のインストールのみ。v0.x プレビュー段階 | OSS。Docker で試せる |
| pg_ducklake | OSS 拡張(MIT)。pg_duckdb と ducklake を基盤に 2026 年 6 月 v1.0.018 | 同一プロセス(DuckDB 実行)。データは DuckLake 形式(Parquet ファイル+メタデータは PostgreSQL カタログ) | heap とは別テーブル。SQL で投入して使う(4,327万行で約 10 秒・4 章)。増分連携は別プロジェクト pg_duckpipe19 | DuckLake テーブルとしてスナップショット・タイムトラベルに対応18。メタデータは PostgreSQL のトランザクションで管理される設計20 | 拡張のインストールのみ(公式 Docker イメージあり) | OSS。Docker で試せる |
②の発想は「分析用の列データを、DB 内でなくデータレイクの標準形式(Iceberg / Parquet)で持つ」です。分析エコシステム(Spark、DuckDB、各社ウェアハウス)とデータを共有できるのが①との違いです。
②の中でも、heap のデータをどう列側へ運ぶかは製品で分かれます。pg_mooncake は heap テーブルのミラーを moonlink が自動で追随させる方式で、CDC 相当の連携を内蔵しています17。一方 pg_lake と pg_ducklake 本体に自動同期はなく(2026 年 7 月時点、公式 README に記載なし)、INSERT INTO ... SELECT や CREATE TABLE AS などの SQL で運ぶか、アプリが最初から Iceberg / DuckLake テーブルへ書く形です。ただし pg_ducklake は、増分の heap から DuckLake への変換を担う別プロジェクト pg_duckpipe を CDC 対応として公式 README で案内しています19。
こばさんの記事1が展望の軸に置いていた DuckLake も、この②の流れにあります。2026 年 4 月に v1.0 となり production-ready を宣言、メタデータを PostgreSQL などの RDBMS カタログに保存する設計で、DuckDB 本体の拡張として提供されています20。「カタログを PostgreSQL 側に置く」という発想は、Iceberg 形式でそれを実現した pg_lake とも共通しています。
こばさんの記事が執筆時点(2025 年 6 月)では連携できないとし、実現を予想していた pg_duckdb × DuckLake の組み合わせ(pg_ducklake)も、その後動きがありました。pg_duckdb 本体への統合プルリクエストは 2026 年 1 月にクローズされましたが、開発者が独立プロジェクトに移行し、2026 年 6 月に pg_ducklake v1.0.0 として公開されています18。pg_duckdb と ducklake 拡張を基盤にした MIT ライセンスの拡張で、PostgreSQL 14〜18 に対応します。予想された名前のまま、本体統合ではなく独立拡張という形で実現したことになります。実際に動くのか・どれくらい速いのかは 4.4 章で実測しています。
3.3. ③ マネージドセット型
| 製品 | 提供形態 | 実行の場所 | データの新しさ | 書き込み整合性 | 運用の重さ | 無料で試せるか |
|---|---|---|---|---|---|---|
| ClickHouse Managed Postgres | ClickHouse Cloud 内のマネージド PG(Beta)21 | 別サービス。分析は ClickHouse、pg_clickhouse でプッシュダウンも可 | ClickPipes(PeerDB 基盤)の CDC で継続同期。同期間隔はポーリング設定制22 | 公式に明文なし(CDC のため結果整合とみられる) | 同一ベンダー内で完結するが、論理的には 2 システム | 無料トライアルあり |
| Databricks Lakebase | Databricks 内のマネージド PG(Autoscaling / Provisioned)23 | 別基盤。分析はレイクハウス(Unity Catalog / Delta)側 | 同期は双方向。UC から PG への synced tables は Continuous モードで最小 15 秒間隔24 | 公式に明文なし。synced table への書き込みは非推奨(読み取り専用運用を推奨) | フルマネージド。Databricks プラットフォームが前提 | Free Edition で利用可 |
| Snowflake Postgres | Snowflake 管理の専用 VM 上の PG。2026 年 2 月 24 日 GA5 | 別サービス。分析は Snowflake 側へ複製して実行 | Openflow Connector for PostgreSQL が「near real-time またはスケジュール」で複製25 | 公式に明文なし(CDC のため結果整合とみられる) | PG 自体はフルマネージド。分析連携には Openflow の設定が別途必要 | 30 日トライアルあり(ただし Openflow はトライアル制限の対象) |
③は「OLTP と OLAP を別エンジンに分けたうえで、接続部分(CDC・カタログ・課金)をベンダーが束ねる」形です。2 システム構成の性質(複製の遅れ、二重のリソース)は残りますが、接続を自作しなくてよいのが利点です。
3.4. ④ zero-ETL・ミラーリング型
| 製品 | 提供形態 | 実行の場所 | データの新しさ | 書き込み整合性 | 運用の重さ | 無料で試せるか |
|---|---|---|---|---|---|---|
| Aurora PostgreSQL zero-ETL | AWS のマネージド統合パイプライン26 | 別サービス(Redshift) | 公式表現は「within seconds」。初期同期はデータ量により 20〜25 分以上 | 結果整合。ソース停止時は直近トランザクションが未複製になりうると明記 | パイプライン構築・維持が不要。統合自体に追加料金なし27 | 恒久無料枠なし(Aurora / Redshift の費用が前提) |
| Fabric ミラーリング(Azure PG) | Microsoft Fabric の機能(GA)28 | 別基盤。OneLake に Delta(Parquet)形式で複製し T-SQL / Spark / Power BI で分析 | 公式表現は「Near real time」。最短 15 秒ごとに反映29 | 結果整合。分析側は読み取り専用コピー | フルマネージド。複製用コンピュートは無料、ミラー用ストレージも一定量無料 | 稼働中の Fabric 容量(有償)が前提 |
④は「PostgreSQL には一切手を入れない」のが特徴です。そのかわり、分析は Redshift や Fabric という別製品の契約・スキルが前提になります。
4. 実測:列データの置き場は本当に性能を左右するのか
2 章の分類軸「列指向のデータと実行をどこに置くか」が、実際どれくらい性能に響くのかを確かめます。まず pg_duckdb です。同じ拡張のまま「データの置き場」だけを変えられるので、この軸を切り分けるのに向いています。続けて 4.4 章で pg_ducklake も測ります。
4.1. 検証環境
| 項目 | 内容 |
|---|---|
| 実行環境 | Windows 11 上の Docker Desktop 29.2.1(VM: 16 CPU / 7.6 GB メモリ) |
| コンテナのリソース制限 | 全コンテナ同一(cpus=8 / メモリ 6 GB / shared_buffers=2GB)。同時には起動せず順番に計測 |
| 素の PostgreSQL | postgres:17(PostgreSQL 17.10) |
| pg_duckdb | pgduckdb/pgduckdb:17-v1.1.1(PostgreSQL 17.7 + DuckDB 1.4.3) |
| pg_ducklake | pgducklake/pgducklake:17-main(PostgreSQL 17.10 + pg_ducklake 1.1.0。4.4 章の追加実測で使用) |
| データ | cell_towers 43,276,150 行30(過去記事313と同一) |
ローカルの Docker 環境なので、絶対値はあくまで参考値です。本記事では 同一環境内の相対比(その環境の行ストア実行を 1.00 とした倍率) だけを比較に使います。計測はいずれもウォームアップ 1 回のあと 3 回実行した平均で、セッション設定(max_parallel_workers_per_gather = 4、work_mem = '256MB')は AlloyDB 記事3と同じにしています。
4.2. クエリ
過去記事から使い続けている 2 本です。
-- (1) radio だけを数える集計(I/O が支配的)。14 列のうち 1 列しか使わない
SELECT radio, count(*) FROM cell_towers GROUP BY radio ORDER BY 2 DESC;
-- (2) 緯度経度を丸めるグリッド集計(CPU 寄り)。行ごとに round() の計算が走る
SELECT count(*) FROM (
SELECT round(lat) AS glat, round(lon) AS glon, radio, count(*) AS c
FROM cell_towers GROUP BY glat, glon, radio
) t;
4.3. 結果:同じ拡張でも 0.43 倍から 32.2 倍まで変わる
結果です(3 回平均。カッコ内は素の PostgreSQL 17 を 1.00 とした倍率)。
| 実行のしかた | radio 集計 | グリッド集計 |
|---|---|---|
| 素の PostgreSQL 17(基準) | 1,079 ms(1.00) | 5,512 ms(1.00) |
| pg_duckdb:PG テーブルを直接読む | 2,490 ms(0.43 倍) | 2,990 ms(1.84 倍) |
| pg_duckdb:同上+読み取りワーカーを 4 に増加 | 3,451 ms(0.31 倍) | 4,293 ms(1.28 倍) |
| pg_duckdb:同じデータを Parquet に変換して読む | 33.5 ms(32.2 倍) | 316 ms(17.4 倍) |
ポイントは 2 つあります。
PG テーブルの直接読みは、単純集計だと素の PostgreSQL より遅くなりました。radio 集計で 0.43 倍です。DuckDB 実行になっていることは実行計画で確認できます(Custom Scan (DuckDBScan))。DuckDB 側のプロファイルを見ると、時間のほとんどが PostgreSQL のテーブルを読む TABLE_SCAN に費やされていました。
Custom Scan (DuckDBScan)
DuckDB Execution Plan:
...
│ TABLE_SCAN │
│ Table: cell_towers │
│ Projections: radio │
│ 43,276,150 rows │
│ (4.13s) │ ← 累積スレッド時間の大半がここ
pg_duckdb が PostgreSQL テーブルを読む並列度はデフォルトで 2 ワーカーです(duckdb.max_workers_per_postgres_scan = 2)。素の PostgreSQL は 4 ワーカーの並列スキャンで走っているので、その差もあります。ただし表のとおり、ワーカーを 4 に増やしても(SET duckdb.max_workers_per_postgres_scan = 4; SET duckdb.threads_for_postgres_scan = 4;)本構成では改善せず、むしろ遅くなりました。行形式のページを読んで列形式に変換するコスト自体が大きい、と読んでいます。
同じデータを Parquet に変換すると、同じ拡張・同じクエリのまま 17〜32 倍になりました。手順は次の 2 つだけです。
-- テーブルを Parquet ファイルに書き出す(5.5 GB のテーブルが 1.32 GB に)
COPY cell_towers TO '/tmp/cell_towers.parquet' (FORMAT parquet);
-- Parquet を直接クエリする(DuckDB 実行になる)
SELECT r['radio'] AS radio, count(*)
FROM read_parquet('/tmp/cell_towers.parquet') r
GROUP BY 1 ORDER BY 2 DESC;
r['radio'] のように取り出した列は、PostgreSQL 側からは duckdb.unresolved_type という型に見えます。GROUP BY や count() はキャスト無しで動きますが、round() など PostgreSQL の関数に渡すと次のエラーになります。
ERROR: function round(duckdb.unresolved_type) does not exist
round((r['lat'])::double precision) のように明示キャストしてください。また psql の \timing はエラーでも 0.1 ms 台の時間を表示するので、計測を自動化していると「大幅に速くなった」と誤読しやすい点にも注意してください(今回一度やりました)。
なお、pg_duckdb は入れただけではクエリの挙動を変えません。duckdb.force_execution = true にしない限り既存クエリは従来の PostgreSQL 実行のままで、実測でも素の PostgreSQL と同等でした(radio 集計 1,125 ms)。既存 OLTP への影響を抑えつつ分析セッションだけ切り替えられる、という意味では扱いやすい設計です。
4.4. pg_ducklake(DuckLake テーブル)でも測る
こばさんの記事の展望どおりに登場した pg_ducklake(3.2 章)でも、同じデータ・同じ 2 クエリを実測しました。コンテナのリソース制限は他と同一、基準は同じコンテナ内の heap テーブル(PostgreSQL 17.10 で、素の PostgreSQL ベースラインとマイナーバージョンまで同じ)です。
手順は「DuckLake テーブルを作って流し込む」だけです。列定義は heap 版と同一です。
CREATE TABLE cell_towers_dl (
radio text,
mcc int,
net int,
area int,
cell bigint,
unit int,
lon double precision,
lat double precision,
range_m bigint,
samples bigint,
changeable smallint,
created timestamp,
updated timestamp,
average_signal smallint
) USING ducklake;
INSERT INTO cell_towers_dl SELECT * FROM cell_towers;
この投入(4,327万行)が約 10.5 秒で終わります。なおこれは一括コピーで、以後の heap 側の更新が DuckLake テーブルへ自動で反映されるわけではありません(増分連携の選択肢は 3.2 章を参照)。結果は次のとおりです(3 回平均。カッコ内は同一コンテナ内の heap を 1.00 とした倍率)。
| 実行のしかた | radio 集計 | グリッド集計 |
|---|---|---|
| heap テーブル(PostgreSQL 実行・基準) | 1,019 ms(1.00) | 4,565 ms(1.00) |
| DuckLake テーブル | 29.7 ms(34.3 倍) | 278.5 ms(16.4 倍) |
実行計画には pg_duckdb の DuckDBScan とは別の専用ノードが現れます。radio 列だけを読む列プルーニングも確認できます。
Custom Scan (DuckLakeScan)
DuckDB Execution Plan:
...
│ DUCKLAKE_SCAN │
│ Table: cell_towers_dl │
│ Projections: radio │
数字は 4.3 の「Parquet に変換して読む」(32.2 倍 / 17.4 倍)とほぼ同じクラスです。DuckLake の実体が「Parquet ファイル+PostgreSQL カタログのメタデータ」であることを考えると自然な結果です。生の Parquet ファイルとの違いは、通常のテーブルとして INSERT でき、スナップショットとして管理される点にあります18。
4.5. 過去記事とならべる:同じデータ・同じクエリの相対比
同じ cell_towers 4,327万件・同じ 2 本のクエリは、過去記事で AlloyDB と ClickHouse でも計測しています。各行の倍率は「その環境の行ストア実行を 1.00 としたときの速さ」です。
| 方式と計測元 | 計測環境 | radio 集計の倍率 | グリッド集計の倍率 | 列データの置き場 |
|---|---|---|---|---|
| ① AlloyDB columnar engine3 | 過去記事。e2-standard-8、基準は同一インスタンスの行ストア | 11.6 倍 | 1.38 倍 | 同一インスタンス内のメモリ列キャッシュ(自動維持) |
| ① pg_duckdb:PG テーブル直接読み | 今回。ローカル Docker | 0.43 倍 | 1.84 倍 | 列データを持たない(行のまま都度読む) |
| ② の形を模擬:pg_duckdb + Parquet | 今回。ローカル Docker | 32.2 倍 | 17.4 倍 | 列形式ファイル(変換時点のスナップショット) |
| ② pg_ducklake:DuckLake テーブル | 今回。ローカル Docker | 34.3 倍 | 16.4 倍 | DuckLake 形式(Parquet + PostgreSQL カタログ) |
| ③ ClickHouse + pg_clickhouse31 | 過去記事。別マシンの構成、基準は 4 vCPU の PostgreSQL | 約 18 倍 | 約 2.4 倍 | 別サービスの列指向 DB(データは複製して保持) |
この表の読み方には注意があります。行をまたいだ倍率の大小比較はできません。たとえば「pg_ducklake の 34.3 倍は ClickHouse の約 18 倍より速い」とは読めません。倍率の分母になる行ストアの速さも、マシンもインスタンスサイズも行ごとに違うためです。横に並べて比較してよいのは「今回」の 3〜4 行(同一マシン・同一リソース制限。ただし pg_ducklake だけ基準が同一コンテナ内の heap なので、32.2 倍と 34.3 倍の差に優劣は付けられません)だけです。
過去記事の行を並べている目的は、各行の中で radio 集計からグリッド集計へ倍率がどう変わるかという方式の性格を見ることです。列キャッシュ型(AlloyDB)や別サービス型(ClickHouse)は 1 列だけ読む集計で大きく伸びて演算入りの集計では倍率が下がる、DuckDB 実行の列ファイル型(Parquet / DuckLake)はどちらのクエリでも 2 桁の倍率を保つ、という形の違いが読み取れます。
5. 考察
同じ DuckDB 系の実行エンジン・同じクエリでも、列データの置き場しだいで radio 集計は 0.43 倍から 34.3 倍まで変わりました。「列指向の分析エンジンを入れたか」ではなく「列形式のデータを用意したか」が分かれ目です。Parquet(32.2 倍)と DuckLake テーブル(34.3 倍)が同じ性能クラスに並んだことも、この見方を裏付けます。2 章の 4 分類は製品の整理のための軸でしたが、そのまま性能の分かれ目でもありました。
radio 集計とグリッド集計で、方式ごとの得意不得意が分かれました。列キャッシュ型の AlloyDB は 1 列だけ読む集計に強く(11.6 倍)、行ごとの round() 計算が重いグリッド集計では 1.38 倍まで下がります。一方 DuckDB 実行の Parquet 読みはグリッド集計でも 17.4 倍を保ちました。
この差は、AlloyDB の列指向エンジンが「読む量の削減」を主に受け持つのに対し、DuckDB は集計・式評価までベクトル化された実行になるためと考えられます(AlloyDB 側の集計実行の内部までは確認していないため、要追加検証)。
速さの代わりに失うものが、データの新しさと運用の手間です。pg_duckdb の直接読みは常に最新のデータを見られますが遅く、Parquet は速い代わりに変換した時点のスナップショットです。AlloyDB の列キャッシュは自動で再構築されますが、頻繁な更新は列キャッシュを無効化します11。③④の CDC・同期系は、Lakebase の synced tables(Continuous)で最小 15 秒間隔24、Fabric ミラーリングは最短 15 秒ごとの反映29、Aurora zero-ETL は「within seconds」26と、それぞれ複製の遅れを持ちます。速さ・データの新しさ・運用の手間のどれかは譲ることになる構図です。
今回の実測は単一セッション・分析クエリ単独の条件です。OLTP と同居させた場合、①エンジン内蔵型は同じインスタンスの CPU・メモリを分析と取り合う点が出てくるはずで(pg_duckdb は同一プロセスに DuckDB のスレッドが同居します)、②〜④が「分析の負荷を外に出せる」利点はその局面で意味を持つと考えられます。pg_duckdb は PostgreSQL の shared_buffers や work_mem とは別に DuckDB 自身のメモリ上限(duckdb.max_memory)を持ち、AlloyDB の列キャッシュはデフォルトでインスタンスメモリの 30% を使うため11、同じ物理メモリを OLTP と分析でどう配分するかという設計項目が増えます。DuckDB 側が上限を超える大きな中間データをメモリに展開した場合、コンテナや OS のメモリ不足で PostgreSQL プロセスごと落ちる可能性も考えられるため、同居運用では duckdb.max_memory の設定が重要になります(今回の実測では発生していません。未検証)。同居時の相互影響は、本記事の実測の範囲外です。
6. 要件別の推奨
前提:正データが PostgreSQL にあり、OLTP は PostgreSQL のまま続ける。提供状況は 2026 年 7 月時点。
要件・状況ごとの入口と、その理由・注意を表にまとめます。読むときの注意がひとつあります。「クエリが速く返るか」と「どれだけ新しいデータを分析できるか」は別の軸です。クエリ応答の速さ自体は③④でも得られます(ClickHouse はミリ秒で返ります)が、正データが PostgreSQL にある以上、③④では CDC・同期の複製の遅れが残ります。
この複製の遅れは、おおむね数秒から数分の範囲で、方式と設定である程度動かせます。たとえば ClickHouse CDC はデフォルト(同期間隔 60 秒)で中央値約 36 秒でしたが、間隔を 1 秒まで詰めると中央値約 1 秒まで下がります。そのかわり ClickHouse 側のマージ負荷が増えるトレードオフがありました32。Aurora zero-ETL の公式表現は「within seconds」、Lakebase と Fabric ミラーリングは最短 15 秒間隔です(3 章の表を参照)。
そのため「どれだけ新しいデータが必要か」は、要件からおおよそ次の 3 段階に分けられます。
- 数分の遅れで問題ない(日次・週次のレポート、BI ダッシュボード): ③④のデフォルト設定で足りる
- 数十秒から数秒まで詰めたい(準リアルタイムの監視・ダッシュボード): CDC 系でも同期間隔の設定しだいで届く。ただし間隔を詰めた分の負荷(マージ等)とのトレードオフを確認する
- 書き込んだ直後の行も集計に含めたい(アプリ内で操作結果が即座に集計へ反映される画面、直前の取引を含めた在庫・与信の判断など): 複製を挟む以上ゼロにはできないため、同じデータを直接読む①が入口になる
| 要件・状況 | まず検討したい選択肢 | 理由と注意 |
|---|---|---|
| 今の PostgreSQL のまま、まず無料で試したい | pg_duckdb | 拡張を入れるだけ。ただし 4 章のとおり、PG テーブルの直接読みでは速くならないことがある。効果が出るのは Parquet / Iceberg など列ソースを併用するとき |
| 時系列データ中心(IoT・ログ・メトリクス) | TimescaleDB Hypercore | 古いチャンクの自動列化と圧縮がこの形に合う。columnstore は Community 版(セルフホスト無料)が必要 |
| BI・Spark など複数のツールやチームで同じデータを分析したい | pg_lake(Iceberg)/ pg_ducklake(DuckLake) | 分析データをレイクハウス形式で持てば、PostgreSQL 以外のエンジンからも同じデータを読める。エコシステムの広さなら Iceberg の pg_lake(pgduck_server とオブジェクトストレージの運用が増える)、手軽さなら pg_ducklake(4.4 章で実測、16〜34 倍) |
| GCP のマネージドで、SQL を変えずに完結したい | AlloyDB | 列キャッシュは自動維持で、アプリの変更なし。1 列だけ読むような集計に特に効果が大きい(11.6 倍)。グリッド集計のような CPU 寄りの処理は伸びが小さい(1.38 倍) |
| 分析の負荷が本番の OLTP に影響を出し始めている | ClickHouse Managed Postgres | 分析を別エンジンに分離すれば OLTP と独立にスケールできる。集計側の伸びは大きい(約 18 倍)。Managed Postgres は Beta である点と、CDC の複製の遅れ(同期間隔設定)を確認してから |
| すでに Databricks / Snowflake が分析基盤 | Lakebase / Snowflake Postgres | 分析基盤側の文脈(カタログ・ガバナンス・課金)に OLTP を寄せる形。Lakebase は Free Edition で試せる |
| AWS / Azure から動けない。DB に手を入れたくない | Aurora zero-ETL / Fabric ミラーリング | PostgreSQL 側の変更が最小。そのかわり分析は Redshift / Fabric の契約とスキルが前提 |
| 書き込んだ直後のデータもすぐ分析対象にしたい | ①エンジン内蔵型から検討 | CDC・同期系は複製の遅れをゼロにはできない(本章冒頭の 3 段階を参照)。①なら同じデータを直接読める(AlloyDB は列キャッシュの再構築頻度を確認) |
7. まとめ
- PostgreSQL の OLTP と OLAP の両立は、列指向のデータと実行を「どこに置くか」で①エンジン内蔵、②レイクハウス連携、③マネージドセット、④zero-ETL・ミラーリングの 4 つに分類できる
- 12 製品を 6 観点(提供形態・実行の場所・データの新しさ・整合性・運用の重さ・無料で試せるか)で比較した。書き込み整合性は公式に明文がない製品が多く、CDC 系は結果整合前提で設計するのが安全
- pg_duckdb / pg_ducklake の実測では、PostgreSQL テーブル直接読みの単純集計が 0.43 倍に対し、同じデータを Parquet / DuckLake 形式に置くと 16〜34 倍。性能を左右するのは製品名でなく列データの置き場だった
- こばさんの記事が展望した pg_ducklake は独立拡張として実現していた(2026 年 6 月 v1.0.0)。4,327万行の投入が約 10 秒・集計 34.3 倍で、展望された「PostgreSQL をインターフェースとしたワンストップな分析」は動く段階に来ている
- そのうえで、データの新しさ・速さ・運用の手間は同時には取れない。要件のどれを優先するかを 6 章の表で絞るのが実務的
8. 参考
- 本記事の起点: こばさんの「pg_duckdbとDuckLakeがもたらすOLAP統合の未来」1
- 使用データ: cell_towers(ClickHouse 公式サンプルデータセット)。元データは OpenCelliD(CC BY-SA 4.0)
- 同じデータ・同じクエリを使った過去記事: AlloyDB 列指向エンジン3、Postgres vs ClickHouse31
- ClickHouse Managed Postgres の実測記事: OLTP 性能2、CDC のレプリケーションラグ32、TPC-H プッシュダウン33
- Databricks Lakebase の実測記事4
-
こば(小林隆浩)さんの「pg_duckdbとDuckLakeがもたらすOLAP統合の未来」(NTT DATA Tech Blog、2025-06-27)。pg_duckdb と DuckLake の仕組みを解説し、pg_duckdb の DuckLake 対応(pg_ducklake)による「PostgreSQL をインターフェースとしたワンストップな分析ツールセット」を展望した記事。本記事の出発点です。https://zenn.dev/nttdata_tech/articles/tzkoba-pgduckdb-ducklake-202506 ↩ ↩2 ↩3
-
ClickHouse の Managed Postgres ベータは本当に RDS より速いのか? 公式 PostgresBench で実測してみた。https://qiita.com/asahide/items/3eec75adda215192df33 ↩ ↩2
-
AlloyDB の列指向エンジンで、同じ SQL のまま 4,327万件の集計がどれだけ速くなるか試した。https://qiita.com/asahide/items/88f783f60f2f974cca35 ↩ ↩2 ↩3 ↩4 ↩5
-
Databricks Lakebase:Unity Catalog 経由の分析はどこで動くか、Free Edition で確かめてみた。https://qiita.com/asahide/items/6596d4fde85a155eff0c ↩ ↩2
-
Snowflake リリースノート "Snowflake Postgres (General availability)"(2026-02-24)。https://docs.snowflake.com/en/release-notes/2026/other/2026-02-24-snowflake-postgres-ga ↩ ↩2
-
Databricks Blog "Mooncake Labs joins Databricks"(2025 年 10 月)。https://www.databricks.com/blog/mooncake-labs-joins-databricks-accelerate-vision-lakebase ↩ ↩2
-
ClickHouse Blog "Fast, scalable, enterprise-grade Postgres natively integrated with ClickHouse"。https://clickhouse.com/blog/postgres-managed-by-clickhouse ↩
-
pg_duckdb(GitHub, duckdb/pg_duckdb)。README に Hydra・MotherDuck との共同開発の経緯と Docker イメージの案内がある。https://github.com/duckdb/pg_duckdb ↩ ↩2 ↩3
-
Snowflake Engineering Blog "Introducing pg_lake"。Crunchy Data 由来の経緯と OSS 化(2025 年 11 月)。https://www.snowflake.com/en/blog/engineering/pg-lake-postgres-lakehouse-integration/ ↩ ↩2
-
paradedb/pg_analytics(GitHub)。README 冒頭に 2025-03-19 アーカイブと pg_search への集約の記載。https://github.com/paradedb/pg_analytics ↩
-
AlloyDB ドキュメント "About the columnar engine"。列キャッシュのメモリ割り当て(デフォルトはインスタンスメモリの 30%)、更新による無効化、再構築の記載。https://docs.cloud.google.com/alloydb/docs/columnar-engine/about ↩ ↩2 ↩3
-
pg_duckdb docs "Transactions"。同一トランザクション内で PostgreSQL テーブルと DuckDB テーブルの両方に書き込めない制約の記載。https://github.com/duckdb/pg_duckdb/blob/main/docs/transactions.md ↩
-
Tiger Data ドキュメント "Compare TimescaleDB editions"。columnstore 系機能が Community 版(TSL)限定である一覧。https://www.tigerdata.com/docs/get-started/choose-your-path/timescaledb-editions ↩
-
Tiger Data ドキュメント "Understand Hypercore"。行ストアから列ストアへの自動変換と、列ストアへの INSERT / UPDATE / DELETE サポートの記載。https://www.tigerdata.com/docs/learn/columnar-storage/understand-hypercore ↩
-
Citus(GitHub, citusdata/citus)。README "Creating Tables with Columnar Storage" に UPDATE / DELETE 非対応の記載。https://github.com/citusdata/citus ↩
-
pg_lake(GitHub, Snowflake-Labs/pg_lake)。README にアーキテクチャ(pgduck_server への処理の切り出し)とトランザクション保証の記載。https://github.com/Snowflake-Labs/pg_lake ↩
-
pg_mooncake(GitHub, Mooncake-Labs/pg_mooncake)。moonlink によるリアルタイム取り込みと pg_duckdb 統合の記載。https://github.com/Mooncake-Labs/pg_mooncake ↩ ↩2
-
pg_ducklake(GitHub, relytcloud/pg_ducklake)。pg_duckdb と ducklake を基盤に、PostgreSQL から DuckLake テーブルを作成・クエリできるようにする拡張。v1.0.0 は 2026-06-17 公開。pg_duckdb 本体への統合プルリクエスト(duckdb/pg_duckdb#830)は 2026-01 にクローズされ、開発者が独立リポジトリへ移行した経緯があります。https://github.com/relytcloud/pg_ducklake ↩ ↩2 ↩3 ↩4
-
pg_duckpipe(GitHub, relytcloud/pg_duckpipe)。pg_ducklake の README が「CDC Support: incremental heap-to-DuckLake conversion」として案内する別拡張。https://github.com/relytcloud/pg_duckpipe ↩ ↩2
-
DuckLake v1.0 発表(2026-04-13)。production-ready 宣言、メタデータを PostgreSQL / SQLite / DuckDB のカタログ DB に保存する設計。https://ducklake.select/2026/04/13/ducklake-10/ ↩ ↩2
-
ClickHouse Cloud ドキュメント "Managed Postgres"(Beta)。https://clickhouse.com/docs/cloud/managed-postgres ↩
-
ClickHouse ドキュメント "Postgres CDC connector in ClickPipes"。同期間隔(ポーリング設定)の記載。https://clickhouse.com/docs/integrations/clickpipes/postgres ↩
-
Databricks ドキュメント "Lakebase Postgres"。Autoscaling / Provisioned の 2 系統。https://docs.databricks.com/aws/en/oltp/projects ↩
-
Databricks ドキュメント "Sync data from Unity Catalog tables"。Snapshot / Triggered / Continuous の 3 モードと最小 15 秒間隔の記載。https://docs.databricks.com/aws/en/oltp/instances/sync-data/sync-table ↩ ↩2
-
Snowflake ドキュメント "Openflow Connector for PostgreSQL"。near real-time またはスケジュールでの複製の記載。https://docs.snowflake.com/en/user-guide/data-integration/openflow/connectors/postgres/about ↩
-
Amazon Aurora User Guide "Aurora zero-ETL integrations"。within seconds の表現、初期同期の所要、ソース停止時の未複製の記載。https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/zero-etl.html ↩ ↩2
-
Aurora zero-ETL 製品ページ(Pricing)。統合自体への追加課金なしの記載。https://aws.amazon.com/rds/aurora/zero-etl/ ↩
-
Microsoft Learn "Mirroring Azure Database for PostgreSQL flexible server"(GA)。https://learn.microsoft.com/en-us/fabric/mirroring/azure-database-postgresql ↩
-
Microsoft Learn "What is Mirroring in Fabric?"。最短 15 秒ごとの反映と、複製用コンピュート・ミラー用ストレージの無料枠の記載。https://learn.microsoft.com/en-us/fabric/mirroring/overview ↩ ↩2
-
cell_towers データセット(ClickHouse 公式)。元データは OpenCelliD、CC BY-SA 4.0。https://clickhouse.com/docs/getting-started/example-datasets/cell-towers ↩
-
同じ4,327万件を Postgres と ClickHouse で集計して比べ、pg_clickhouse で Postgres から ClickHouse に集計を任せてみた。https://qiita.com/asahide/items/54d5652357692dd36e64 ↩ ↩2 ↩3
-
ClickHouse Managed Postgres の CDC はどれくらい速い? Postgres→ClickHouse の増分レプリ遅延を実測してみた。https://qiita.com/asahide/items/e9d930c90e8f893b8a42 ↩ ↩2
-
Postgres から ClickHouse へフェデレーテッドクエリ(pg_clickhouse)。TPC-H 22 本のプッシュダウンを SF1 と SF10 で実測。https://qiita.com/asahide/items/cb1af815777bb4f15bb6 ↩