インスタンス間のクエリは、外部データラッパー (FDW) を使用して、同一の Alibaba Cloud アカウントに属する AnalyticDB for PostgreSQL インスタンス間でフェデレーテッドクエリを実行する機能です。データが複数のインスタンスに分散しており、データを複製することなく、クエリ対象のデータを最新の状態に保つ必要がある場合に使用します。
仕組み
多くの企業や組織では、それぞれが異なるビジネスやアプリケーション専用の複数の AnalyticDB for PostgreSQL インスタンスを同時に実行しています。業務部門でフェデレーテッド分析が必要な場合など、特定のケースでは、これらのインスタンス間でデータをクエリする必要があります。従来、フェデレーテッド分析は、以下のいずれかの方法で実装されていました。
-
異なるインスタンスにデータの同一コピーを保存する。このアプローチは、ビジネス上の混乱やデータの冗長性を引き起こす可能性があります。
-
Object Storage Service (OSS) などの単一の共有ストレージサービスにデータを保存する。このアプローチでは、データの適時性を保証できません。
上記の問題を解決するため、Alibaba Cloud チームは AnalyticDB for PostgreSQL の MPP アーキテクチャに基づき、コンピュートノードを相互接続する FDW を設計・実装しました。この FDW は、コンピュートノードを最大限に活用して、インスタンス間でデータに並列アクセスし、データアクセス効率を向上させます。このアプローチは、PostgreSQL のネイティブな postgres_fdw の数倍のパフォーマンスを実現します。測定結果については、本トピックの「パフォーマンス」セクションをご参照ください。

制限事項
AnalyticDB for PostgreSQL のインスタンス間のクエリには、以下の制限事項が適用されます。
-
サポートされる操作 — 外部テーブルは `SELECT` と `INSERT` のみをサポートします。`UPDATE` と `DELETE` はサポートされていません。
-
インスタンスモードとカーネルバージョン — 高速なインスタンス間クエリは、以下の表に記載されているデータベースカーネルバージョンでのみサポートされます。プッシュダウン機能や、外部テーブルの実行計画を生成するオプティマイザーも、インスタンスモードに依存します。
| インスタンスモード | 最小カーネルバージョン | JOIN および集計プッシュダウン | 外部テーブル用オプティマイザー |
| 弾性ストレージモード V7.0 | V7.0.1.x 以降 | サポート | Orca オプティマイザー |
| 弾性ストレージモード V6.0 | V6.3.11.2 以降 | 非サポート | ネイティブオプティマイザー |
| Serverless モード | V1.0.6.x 以降 | 非サポート | ネイティブオプティマイザー |
-
FDW 外部テーブルは `SELECT` および `INSERT` 操作のみをサポートします。`UPDATE` および `DELETE` 操作はサポートされていません。
-
弾性ストレージモード V7.0 のみ、JOIN プッシュダウンと集計プッシュダウンをサポートします。
-
弾性ストレージモード V7.0 の ORCA オプティマイザーのみが、FDW 外部テーブルの実行計画を生成できます。弾性ストレージモード V6.0 および Serverless モードの ORCA オプティマイザーは外部テーブルを処理できず、ネイティブオプティマイザーにフォールバックします。
ソースインスタンス (データがアクセスされるインスタンス) が Serverless モードで実行されている場合、インスタンスのスケーリング中はデータにアクセスできません。
前提条件
このトピックの手順では、2 つのインスタンスを使用します。インスタンス A はクエリを実行する宛先インスタンス、インスタンス B はデータにアクセスするソースインスタンスです。以下の要件が満たされていることを確認してください。
-
インスタンス A とインスタンス B は、同一の Alibaba Cloud アカウントに属し、同一のリージョンおよびアベイラビリティゾーンに配置されています。
-
インスタンス A とインスタンス B のインスタンスモードとデータベースカーネルバージョンが、本トピックの「制限事項」セクションの要件を満たしている必要があります。
-
psql クライアントは、インスタンス A およびインスタンス B への接続に利用できます。
-
インスタンス B のデータベースアカウントに、
db02データベースに対する読み取り権限が必要です。外部テーブルで `INSERT` 操作を実行する場合は、書き込み権限も必要です。手順については、「アカウントの作成と管理」をご参照ください。 -
AnalyticDB for PostgreSQL インスタンスのパスワード認証方式が変更されました。AnalyticDB for PostgreSQL V6.0 インスタンスまたは Serverless インスタンスが AnalyticDB for PostgreSQL V7.0 インスタンスにアクセスする前に、チケットを送信してテクニカルサポートにご連絡いただく必要があります。
操作手順
以下の手順では、インスタンス A とインスタンス B の間でインスタンス間のクエリを有効にする方法について説明します。設定が完了すると、インスタンス A の db01 データベースに接続して、インスタンス B の db02 データベース内のテーブルにアクセスし、コンピュートノード間の高速相互接続を介してローカルテーブルとリモートテーブルを結合するフェデレーテッドクエリを実行できます。アカウント、リージョン、アベイラビリティゾーンの要件については、本トピックの「前提条件」セクションをご参照ください。
-
psql クライアントを使用してインスタンス A とインスタンス B に接続します。手順の詳細については、「クライアント接続」をご参照ください。
-
インスタンス A とインスタンス B にデータベースを作成します。
インスタンス A で
db01データベースを作成し、それに切り替えます。CREATE DATABASE db01; \c db01db02CREATE DATABASE db02; \c db02 -
インスタンス A の
db01データベースとインスタンス B のdb02データベースで、インスタンス間のクエリに必要なgreenplum_fdwおよびgp_parallel_retrieve_cursor拡張機能を作成します。手順の詳細については、「拡張機能のインストール、更新、アンインストール」をご参照ください。 -
インスタンス A の内部 IP アドレスを取得し、インスタンス B のホワイトリストに追加します。ホワイトリストの設定方法の詳細については、「IP アドレスホワイトリストの設定」をご参照ください。
インスタンス A で、次の SQL ステートメントを実行して内部 IP アドレスを取得します。
SELECT dbid, address FROM gp_segment_configuration; -
インスタンス B の
db02データベースで、テストデータを準備します。CREATE SCHEMA s01; CREATE TABLE s01.t1(a int, b int, c text); CREATE TABLE s01.t2(a int, b int, c text); CREATE TABLE s01.t3(a int, b int, c text); INSERT INTO s01.t1 VALUES(generate_series(1,10),generate_series(11,20),'t1'); INSERT INTO s01.t2 VALUES(generate_series(11,20),generate_series(11,20),'t2'); INSERT INTO s01.t3 VALUES(generate_series(21,30),generate_series(11,20),'t3'); -
インスタンス A の
db01データベースで、サーバーとユーザーマッピングを作成します。-
サーバーを作成します。
CREATE SERVER remote_adbpg FOREIGN DATA WRAPPER greenplum_fdw OPTIONS (host 'gp-xxxxxxxx-master.gpdb.zhangbei.rds.aliyuncs.com', port '5432', dbname 'db02');パラメーター 説明 host インスタンス B の内部エンドポイントです。AnalyticDB for PostgreSQL コンソールにログインします。インスタンス B の [基本情報] ページで、[データベース接続] セクションの [内部エンドポイント] を取得します。 port インスタンス B の内部エンドポイントのポート番号です。デフォルト値は 5432です。dbname ソースデータベースの名前です。この例では、値は db02です。 -
ユーザーマッピングを作成します。詳細については、PostgreSQL ドキュメントの「CREATE USER MAPPING」をご参照ください。
CREATE USER MAPPING FOR PUBLIC SERVER remote_adbpg OPTIONS (user 'report', password '******');パラメーター 説明 user インスタンス B のデータベースアカウントです。このアカウントに必要な権限については、本トピックの「前提条件」セクションをご参照ください。 password 上記アカウントのパスワードです。
-
-
インスタンス A の
db01データベースで、リモートテーブルをマッピングします。リモートテーブルは、次の 2 つの方法のいずれかでマッピングできます。各外部テーブルの定義をカスタマイズする必要がある場合は、ソーステーブルごとに外部テーブルを作成します。複数のテーブルを迅速にマッピングする必要がある場合は、スキーマからすべてのテーブルをインポートします。どちらの方法でも
db01データベースにs01スキーマが作成されるため、2 つの方法のうち 1 つだけを使用してください。-
ソーステーブルごとに外部テーブルを作成する。
この方法には、次の利点と欠点があります。
-
利点: 外部テーブルの DDL を柔軟にカスタマイズできます。たとえば、
db02データベースのテーブルt1には、a、b、cという 3 つの列があります。ターゲットデータベースで列aとbのみが必要な場合、外部テーブルを作成するときにこれらの列を指定できます。 -
欠点:各テーブルの DDL を知っている必要があります。複数の外部テーブルを一度に 1 つずつインポートするのは面倒です。
CREATE SCHEMA s01; CREATE FOREIGN TABLE s01.t1(a int, b int) server remote_adbpg options(schema_name 's01', table_name 't1'); -
-
ソースデータベースのスキーマ内のすべてのテーブルをインポートする。
この方法には、次の利点と欠点があります。
-
利点:各テーブルの DDL を知らなくても、外部テーブルを迅速にインポートできます。
-
欠点:この方法は柔軟性に欠けます。各外部テーブルの名前はソースデータベースのものと同じで、列も同様です。
IMPORT FOREIGN SCHEMA」をご参照ください。CREATE SCHEMA s01; IMPORT FOREIGN SCHEMA s01 LIMIT TO (t1, t2, t3) FROM SERVER remote_adbpg INTO s01;
-
-
-
インスタンス A の
db01データベースで、インスタンス B のdb02データベースのデータをクエリします。SELECT * FROM s01.t1;a | b | c ----+----+---- 2 | 12 | t1 3 | 13 | t1 4 | 14 | t1 7 | 17 | t1 8 | 18 | t1 1 | 11 | t1 5 | 15 | t1 6 | 16 | t1 9 | 19 | t1 10 | 20 | t1 (10 rows)
パフォーマンス
次の図は、ローカルクエリとインスタンス間のクエリを比較した TPC-H パフォーマンステストの結果を示しています。このテストは 1 TB のデータセットで実行されました。

TPC-H 1 TB データセットなどのビッグデータシナリオでは、インスタンス間のクエリのパフォーマンスは、ローカルクエリの約 50% です。
クエリの最適化
インスタンス間のクエリでは、ネットワーク経由でデータが転送されます。ネットワーク I/O を削減するために、外部テーブルをクエリする際は、常に WHERE 句にフィルター条件を追加してください。
リファレンス
AnalyticDB for PostgreSQL は、データベース間のクエリもサポートしています。詳細については、「データベース間のデータクエリ」をご参照ください。