[アップデート] Amazon Aurora PostgreSQL 18.3 がリリースされたので、Babelfish 6.0 のアップデート内容を確認してみた

[アップデート] Amazon Aurora PostgreSQL 18.3 がリリースされたので、Babelfish 6.0 のアップデート内容を確認してみた

2026.06.14

いわさです。

Aurora PostgreSQL のメジャーバージョン 18 がリリースされました。
PostgreSQL 18 では B-tree skip scan やメジャーバージョンアップグレード時のオプティマイザ統計保持など、パフォーマンス面の改善が入っています。

https://dev.classmethod.jp/articles/aurora-postgresql-18-3-new-features/

Aurora PostgreSQL の新しいメジャーバージョンがリリースされたということは、Babelfish バージョンも新しいものがあわせてリリースされています。
以前、こちらの記事で Aurora PostgreSQL 17.9 + Babelfish 5.5 のアップデート内容を紹介しています。

https://dev.classmethod.jp/articles/aurora-postgresql-17-9-babelfish-5-5/

今回は Babelfish 5.x から 6.x へのメジャーバージョンアップとなっており、新たに Eager aggregation 機能が追加されています。
これは集約処理を JOIN の前に押し下げることでクエリパフォーマンスを改善する最適化です。

実際にコンソールのバージョン選択を見ても、18.3 が選択肢に追加されています。

51B02A8B-8FE2-4F2D-A19B-BAF1A5DB3A70_4_5005_c.jpeg

今回こちらを確認してみたので紹介します。

バージョン確認

まずは psql から Babelfish のバージョン確認を行います。

% psql -h hoge-babelfish6.cluster-cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com -U postgres -d babelfish_db
Password for user postgres: 
psql (14.15 (Homebrew), server 18.3)
WARNING: psql major version 14, server major version 18.
         Some psql features might not work.
Type "help" for help.

babelfish_db=> SELECT aurora_version() AS aurora_version, version() AS postgresql_version, sys.version() AS Babelfish_compatibility, sys.SERVERPROPERTY('BabelfishVersion') AS Babelfish_Version;
 aurora_version |                                              postgresql_version                                              |                           babelfish_compatibility                           | babelfish_version 
----------------+--------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+-------------------
 18.3.0         | PostgreSQL 18.3 on aarch64-unknown-linux-gnu, compiled by aarch64-unknown-linux-gnu-gcc (GCC) 10.5.0, 64-bit | Babelfish for Aurora PostgreSQL with SQL Server Compatibility - 12.0.2000.8+| 6.0.0
                |                                                                                                              | May 21 2026 22:55:57                                                       +| 
                |                                                                                                              | Copyright (c) Amazon Web Services                                          +| 
                |                                                                                                              | PostgreSQL 18.3 on aarch64-unknown-linux-gnu (Babelfish 6.0.0)              | 
(1 row)

Babelfish バージョンは 6.0.0 ですね。
互換性は SQL Server Compatibility - 12.0.2000.8+(SQL Server 2014)のままです。ここは変わらないですね。

sqlcmd からも確認してみます。

% sqlcmd -S hoge-babelfish6.cluster-cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U postgres -N -C -Q "SELECT @@VERSION AS version;"
version                                                                                    
-------------------------------------------------------------------------------------------
Babelfish for Aurora PostgreSQL with SQL Server Compatibility - 12.0.2000.8
May 21 2026 22:55:57
Copyright (c) Amazon Web Services
PostgreSQL 18.3 on aarch64-unknown-linux-gnu (Babelfish 6.0.0)                             

(1 row affected)

Babelfish 6.0 の新機能を確認

では Babelfish 6.0 で新しく使えるようになった機能を確認してみましょう。
リリースノートは以下です。

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraBabelfish.Updates.html

今回の新機能は以下の 4 つです。

  • Eager aggregation のサポート(JOIN の前に集約を押し下げてクエリパフォーマンスを改善)
  • geography/geometry データタイプで Polygon インスタンスがサポート
  • (n)varchar/(n)char から datetimeoffset データタイプへの暗黙キャストがサポート
  • sys.fn_varbintohexstr システムオブジェクトがサポート

Babelfish 5.5 でも追加されていた Polygon、datetimeoffset 暗黙キャスト、sys.fn_varbintohexstr は引き続き含まれていますが、6.0 の目玉は Eager aggregation です。
これは Babelfish 5.x にはなかった新機能で、集約処理を JOIN の前に実行することで JOIN で処理する行数を削減しクエリパフォーマンスを改善する最適化です。

そのほかバグ修正として、AD 認証有効時の PostgreSQL エンドポイントからのクエリ実行で再起動が発生しうる問題や、OUTPUT 句付き UPDATE で並行更新時に行がスキップされる問題、pyODBC 接続時の高 CPU 使用率の問題なども修正されています。

今回は 6.0 固有の新機能である Eager aggregation を中心に確認してみます。

Eager aggregation

Eager aggregation は GUC(Grand Unified Configuration、PostgreSQL のサーバー設定パラメータ)babelfishpg_tsql.enable_eager_aggregate(デフォルト: ON)で制御されます。
また、min_eager_agg_group_size(デフォルト: 8)で、Eager aggregation を適用するかどうかの閾値を設定できるみたいです。
1グループあたりの平均行数がこの値以上の場合に、オプティマイザが Eager aggregation の適用を検討するようですね。

なお、この Eager aggregation は SQL Server の互換機能ではなく、Aurora PostgreSQL / Babelfish 独自のクエリ最適化です。
PostgreSQL 18 コミュニティ版のリリースノートにも該当する機能は見当たらず、Aurora PostgreSQL 18.3 のリリースノートに Aurora 固有の新機能として記載されています。
SQL Server にも同様のアプローチはオプティマイザ内部に存在しますが、明示的に「Eager aggregation」という名前で文書化されてはいないようです。

公式ドキュメントのリリースノートによると、以下のように説明されています。

Added support for Eager aggregation, which pushes aggregation before joins to improve query performance. Controlled by GUCs babelfishpg_tsql.enable_eager_aggregate (default: ON) and min_eager_agg_group_size to set the minimum average group size required to consider applying Eager aggregation (default: 8).

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraBabelfish.Updates.html

なお、Aurora PostgreSQL 18.3 自体にも enable_eager_aggregate という GUC がありますが、こちらはデフォルト OFF とのこと。
Babelfish 側の GUC はデフォルト ON なので、TDS ポート経由で T-SQL を実行した場合には自動的に Eager aggregation が有効になるようですね。

実際に psql から GUC の値を確認してみます。

babelfish_db=> SHOW babelfishpg_tsql.enable_eager_aggregate;
 babelfishpg_tsql.enable_eager_aggregate 
-----------------------------------------
 on
(1 row)

babelfish_db=> SHOW min_eager_agg_group_size;
 min_eager_agg_group_size 
--------------------------
 8
(1 row)

babelfish_db=> SHOW enable_eager_aggregate;
 enable_eager_aggregate 
------------------------
 off
(1 row)

Babelfish 側の GUC(babelfishpg_tsql.enable_eager_aggregate)は ON、PostgreSQL ネイティブの GUC(enable_eager_aggregate)は OFF になっていることが確認できます。

実行プランで動作を確認

Eager aggregation の効果を実行プランで確認してみます。
今回は注文テーブル(10万行)と注文明細テーブル(50万行)を用意して、JOIN + GROUP BY のクエリで比較しました。

まず enable_eager_aggregate = on の場合です。

babelfish_db=> SET enable_eager_aggregate = on;
babelfish_db=> SET min_eager_agg_group_size = 1;
babelfish_db=> EXPLAIN (COSTS ON, ANALYZE, BUFFERS) SELECT o.order_id, SUM(oi.qty) AS total_qty
FROM Orders o JOIN order_items oi ON o.order_id = oi.order_id
GROUP BY o.order_id;
                                                                QUERY PLAN                                                 
---------------------------------------------------------------------------------------------------------------------------
 Finalize HashAggregate  (cost=15015.52..16069.07 rows=84284 width=8) (actual time=375.675..413.916 rows=99290 loops=1)
   Group Key: o.order_id
   Batches: 1  Memory Usage: 6169kB
   Buffers: shared hit=3780
   ->  Hash Join  (cost=13530.00..14594.10 rows=84284 width=12) (actual time=268.291..341.610 rows=99290 loops=1)
         Hash Cond: (oi.order_id = o.order_id)
         Buffers: shared hit=3780
         ->  Partial HashAggregate  (cost=10685.00..11527.84 rows=84284 width=12) (actual time=238.873..268.765 rows=99290 loops=1)
               Group Key: oi.order_id
               Batches: 1  Memory Usage: 6169kB
               Buffers: shared hit=3185
               ->  Seq Scan on order_items oi  (cost=0.00..8185.00 rows=500000 width=8) (actual time=0.015..70.705 rows=500000 loops=1)
                     Buffers: shared hit=3185
         ->  Hash  (cost=1595.00..1595.00 rows=100000 width=4) (actual time=29.329..29.331 rows=100000 loops=1)
               Buckets: 131072  Batches: 1  Memory Usage: 4540kB
               Buffers: shared hit=595
               ->  Seq Scan on orders o  (cost=0.00..1595.00 rows=100000 width=4) (actual time=0.095..11.131 rows=100000 loops=1)
                     Buffers: shared hit=595
 Planning Time: 1.738 ms
 Execution Time: 420.747 ms
(20 rows)

Partial HashAggregateSeq Scan on order_items の直後に配置されています。
これが Eager aggregation の動作で、50万行ある order_items を JOIN する前に order_id で事前集約し、約9.9万行に削減してから JOIN を実行しています。

次に enable_eager_aggregate = off にして同じクエリを実行します。

babelfish_db=> SET enable_eager_aggregate = off;
babelfish_db=> EXPLAIN (COSTS ON, ANALYZE, BUFFERS) SELECT o.order_id, SUM(oi.qty) AS total_qty
FROM Orders o JOIN order_items oi ON o.order_id = oi.order_id
GROUP BY o.order_id;
                                                             QUERY PLAN                                                     
----------------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=14842.56..16092.56 rows=100000 width=8) (actual time=509.593..551.911 rows=99290 loops=1)
   Group Key: o.order_id
   Batches: 5  Memory Usage: 8249kB  Disk Usage: 200kB
   Buffers: shared hit=3780, temp read=4 written=26
   ->  Hash Join  (cost=2845.00..12342.56 rows=500000 width=8) (actual time=30.042..319.167 rows=500000 loops=1)
         Hash Cond: (oi.order_id = o.order_id)
         Buffers: shared hit=3780
         ->  Seq Scan on order_items oi  (cost=0.00..8185.00 rows=500000 width=8) (actual time=0.015..70.838 rows=500000 loops=1)
               Buffers: shared hit=3185
         ->  Hash  (cost=1595.00..1595.00 rows=100000 width=4) (actual time=29.951..29.952 rows=100000 loops=1)
               Buckets: 131072  Batches: 1  Memory Usage: 4540kB
               Buffers: shared hit=595
               ->  Seq Scan on orders o  (cost=0.00..1595.00 rows=100000 width=4) (actual time=0.081..11.241 rows=100000 loops=1)
                     Buffers: shared hit=595
 Planning Time: 1.670 ms
 Execution Time: 558.332 ms
(16 rows)

OFF の場合は 50万行をそのまま JOIN してから集約しています。
結果を比較すると以下のようになります。

設定 実行時間 Disk Usage
Eager aggregation ON 420ms なし
Eager aggregation OFF 558ms 200kB

Eager aggregation ON の場合、JOIN の前に集約が行われることで JOIN 対象の行数が 50万→約9.9万に削減されています。
その結果、メモリ消費が抑えられディスクへの一時ファイル書き込みも不要になり、約 25% の実行時間短縮が確認できました。良いですね!

go-sqlcmd 1.9.0 は引き続き一部クエリで TDS エラー

前回の記事(Babelfish 5.5)で go-sqlcmd 1.9.0 の TDS プロトコルエラーを報告しましたが、Babelfish 6.0 でも GROUP BY を含むクエリで同様のエラーが発生しました。

% sqlcmd --version
sqlcmd: Install/Create/Query SQL Server, Azure SQL, and Tools

Version: 1.9.0
% sqlcmd -S hoge-babelfish6.cluster-cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U postgres -N -C -Q "SELECT customer_id, SUM(amount) AS total FROM SmallOrders GROUP BY customer_id ORDER BY customer_id;"
customer_id total                                   
----------- ----------------------------------------
Invalid TDS stream: unknown token type returned: token(165)

単純な SELECT 1SELECT @@VERSION は問題なく動作しますが、GROUP BY を含むクエリで TDS ストリームエラーが発生するみたいです。
前回 Babelfish 5.5 では SELECT 1 でもエラーが出ていたので、部分的には改善されているのかもしれません。

引き続き go-sqlcmd で問題が出た場合は mssql-tools18(旧 sqlcmd)や pymssql の利用を検討してみてください。

さいごに

本日は Amazon Aurora PostgreSQL 18.3 がリリースされたので、Babelfish 6.0 のアップデート内容を確認してみました。

Babelfish 5.x から 6.x へのメジャーバージョンアップということで、Eager aggregation という新しいクエリ最適化が追加されたのが今回の目玉です。
集約を JOIN の前に押し下げることで JOIN 対象の行数を減らすアプローチで、大量データの集約クエリでは実行時間の短縮が期待できそうです。
Babelfish 側のデフォルトでは ON になっているので、TDS ポート経由で接続している場合は自動的に恩恵を受けられるのは良いですね。

go-sqlcmd 1.9.0 の TDS エラーは引き続き特定のクエリパターンで発生するみたいなので、こちらは go-sqlcmd 側のアップデートで改善されることに期待したい。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事