すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB RDS:Pgvector 性能テスト (HNSW インデックス)

最終更新日:May 10, 2026

本トピックでは、ApsaraDB RDS for PostgreSQL インスタンス上で HNSW インデックスを使用した pgvector 拡張の性能ベンチマークを紹介します。このベンチマークでは、ann-benchmarks ツールを使用して、RDS 実装とコミュニティ版の取得率、秒間クエリ数 (QPS)、インデックス構築時間などの主要メトリックを比較評価します。

テスト環境

ネットワークの変動による誤差を避けるため、ご利用の RDS PostgreSQL インスタンスとクライアント ECS インスタンスを同一の Virtual Private Cloud (VPC) および VSwitch 内に配置してください。

コンポーネント

説明

RDS PostgreSQL インスタンス

  • メジャーバージョン: RDS PostgreSQL 17

  • インスタンスタイプ: pg.x4.2xlarge.1

  • pgvector プラグインバージョン: 0.8.0.1

ECS インスタンス

  • インスタンスタイプ: ecs.c6.xlarge (4 コア、8 GiB)

  • オペレーティングシステム: Alibaba Cloud Linux 3

テストツール

ANN-Benchmarks

重要

デフォルトでは、ANN-Benchmarks はシングルスレッドの性能をテストします。インスタンスの同時性能をテストするには、「pgvector 性能テスト (IVF インデックスに基づく)」をご参照ください。

前提条件

RDS for PostgreSQL インスタンス

  1. 高権限アカウント ann_testuser とテストデータベース ann_testdb を作成します。詳細については、「アカウントとデータベースの作成」をご参照ください。

  2. ann_testdb データベースに pgvector プラグイン (ベクター) をインストールします。詳細については、「プラグインの管理」をご参照ください。

クライアント ECS インスタンス

  1. Docker をインストールします。詳細については、「Docker をインストールする」をご参照ください。

  2. 次のコマンドを実行して、ann-benchmarks ツールをダウンロードします。

    cd ~
    git clone https://github.com/erikbern/ann-benchmarks.git
  3. 次のコマンドを実行して、Conda を使用して ann_test という名前の Python 3.10.6 仮想環境を作成し、有効化します。

    yum install git
    yum install conda
    conda create -n ann_test python=3.10.6
    conda init bash
    source /usr/etc/profile.d/conda.sh 
    conda activate ann_test
  4. 次のコマンドを実行して、ann-benchmarks の依存関係をインストールします。

    cd ~/ann-benchmarks/
    pip install -r requirements.txt

テスト手順

重要

この手順のすべてのステップは ann_test 仮想環境内で実行されます。セッションがタイムアウトまたは何らかの理由で終了した場合は、コマンド conda activate ann_test を使用して環境に再入力してください。

ステップ 1: 接続設定の構成

ベンチマークツール内の ~/ann-benchmarks/ann_benchmarks/algorithms/pgvector/module.py ファイルを編集し、次の接続設定を追加します。実際の環境に基づいて値を入力してください。

# PostgreSQL の接続パラメーターを設定
os.environ['ANN_BENCHMARKS_PG_USER'] = 'ann_testuser'     # RDS PostgreSQL インスタンスのユーザー
os.environ['ANN_BENCHMARKS_PG_PASSWORD'] = 'testPawword'  # RDS PostgreSQL ユーザーのパスワード
os.environ['ANN_BENCHMARKS_PG_DBNAME'] = 'ann_testdb'     # RDS PostgreSQL インスタンスのデータベース名
os.environ['ANN_BENCHMARKS_PG_HOST'] = 'pgm-****.pg.rds.aliyuncs.com'  # RDS PostgreSQL インスタンスの内部エンドポイント
os.environ['ANN_BENCHMARKS_PG_PORT'] = '5432'             # RDS PostgreSQL インスタンスの内部ポート番号
os.environ['ANN_BENCHMARKS_PG_START_SERVICE'] = 'false'   # 自動サービス起動を無効化

ステップ 2: ann-benchmarks テストパラメーターの構成

テスト要件に基づき、ベンチマークツール内の ~/ann-benchmarks/ann_benchmarks/algorithms/pgvector/config.yml ファイルを編集します。例を以下に示します。

float:
  any:
  - base_args: ['@metric']
    constructor: PGVector
    disabled: false
    docker_tag: ann-benchmarks-pgvector
    module: ann_benchmarks.algorithms.pgvector
    name: pgvector
    run_groups:
      M-16(100):
        arg_groups: [{M: 16, efConstruction: 100}]
        args: {}
        query_args: [[10, 20, 40, 80, 120, 200, 400, 800]]
      M-16(200):
        arg_groups: [{M: 16, efConstruction: 200}]
        args: {}
        query_args: [[10, 20, 40, 80, 120, 200, 400, 800]]
      M-24(200):
        arg_groups: [{M: 24, efConstruction: 200}]
        args: {}
        query_args: [[10, 20, 40, 80, 120, 200, 400, 800]]                                                            

このテストは、M-16(100)、M-16(200)、M-24(200) の 3 つのグループに分かれています。arg_groups は HNSW インデックス作成時のパラメーターを、query_args は取得時のパラメーターをそれぞれ設定します。

パラメーター

説明

arg_groups

M

HNSW インデックスの m パラメーターに対応します。HNSW インデックス構築時に各レイヤーの各ノードが持つ最大近傍数を指定します。

値を大きくするとグラフの密度が増し、一般に取得率が向上しますが、インデックス構築時間およびクエリ時間が長くなります。

efConstruction

HNSW インデックスの ef_construction パラメーターに対応します。インデックス構築時のサンプル候補セットのサイズを指定し、最適な接続を選択する際に評価される候補ノード数を決定します。

値を大きくすると一般に取得率が向上しますが、インデックス構築時間およびクエリ時間が長くなります。

query_args

ef_search

検索処理中に維持されるサンプル候補セットのサイズを指定するクエリ時設定です。

値を大きくすると一般に取得率が向上しますが、クエリ時間が長くなります。

ステップ 3: テスト用 Docker イメージのビルド

  1. (任意)PostgreSQL のコミュニティ版(デフォルト)のテストをスキップするには、~/ann-benchmarks/ann_benchmarks/algorithms/pgvector/Dockerfile ファイルを次のように変更します。

    FROM ann-benchmarks
    USER root
    RUN pip install psycopg[binary] pgvector
  2. --algorithm pgvector を指定して install.py を実行し、テスト用 Docker イメージをビルドします。

    cd ~/ann-benchmarks/
    python install.py --algorithm pgvector
    説明

    サポートされているパラメーターを表示するには、python install.py --help を実行します。

ステップ 4: データセットの取得

ベンチマークスクリプトは、指定されたパブリックデータセットを自動的にダウンロードします。

本トピックでは、テキスト類似検索の例として Angular 距離タイプを使用する nytimes-256-angular データセットを使用します。その他のパブリックデータセットについては、「ann-benchmarks」をご参照ください。

データセット

ディメンション

行数

テストベクター

Top-N 近傍

距離タイプ

NYTimes

256

290,000

10,000

100

Angular

説明

パブリックデータセットがテスト要件を満たさない場合は、実際のベクトルデータを HDF5 などの標準フォーマットに変換して取得パフォーマンスをテストすることを推奨します。詳細については、「付録 II: カスタムテストデータセット」をご参照ください。

ステップ 5: テストの実行と結果の取得

  1. 次のコマンドを使用してベンチマークスクリプトを実行します。

    cd ~/ann-benchmarks
    nohup python run.py --dataset nytimes-256-angular -k 10  --algorithm pgvector --runs 1 > ann_benchmark_test.log 2>&1 &
    tail -f ann_benchmark_test.log

    パラメーター

    説明

    --dataset

    テスト対象のデータセットを指定します。

    --k

    クエリ SQL ステートメントの LIMIT 値、つまり返される結果の数です。

    --algorithm

    テスト対象のベクトルデータベースアルゴリズムです。今回のテストでは pgvector を指定します。

    --runs

    テスト実行回数です。複数回の実行結果から最良の結果が選択されます。

    --parallelism

    テストの同時実行数です。デフォルトは 1 です。

  2. 次のコマンドを実行して、テスト結果のプロットを生成します。

    cd ~/ann-benchmarks
    python plot.py --dataset nytimes-256-angular --recompute

    インデックス構築メトリックおよび同一取得率における性能向上に注目してください。

    インデックス構築の比較:

    インデックスタイプ

    作成時間 (秒)

    インデックスサイズ

    HNSW コミュニティ版 (v0.8.0)

    127.89

    7820 MB

    HNSW RDS 版 (v0.8.0.1)

    77.72

    3916 MB

    同一取得率における QPS の比較:

    再現率

    v0.8.0 HNSW パラメーター

    v0.8.0.1 HNSW パラメーター

    v0.8.0 QPS

    v0.8.0.1 QPS

    97%

    ef_search=10

    ef_search=10

    1635.41

    1954.48

    98%

    ef_search=30

    ef_search=20

    1075.49

    1379.61

    99.3%

    ef_search=120

    ef_search=80

    434.74

    737.06

    99.5%

    ef_search=300

    ef_search=350

    200.06

    319.19

    99.6%

    ef_search=500

    ef_search=500

    109.51

    177.94

  3. (任意)次のコマンドを実行して、詳細なテスト結果を CSV ファイルにエクスポートします。

    cd ~/ann-benchmarks
    python data_export.py --out res.csv

    たとえば、mef_construction パラメーターとインデックス構築時間の関係を分析できます。

    m

    ef_construction

    構築時間 (秒)

    16

    100

    33.35161

    16

    200

    57.66014

    24

    200

    87.22608

結論

HNSW インデックスを構築する場合:

  • mef_construction、および ef_search を増やすと取得率が向上しますが、QPS は低下します。

  • m および ef_construction を増やすと取得率が向上しますが、同時に QPS が低下し、インデックス構築時間が長くなります。

  • アプリケーションで高い取得率が求められる場合は、デフォルトのインデックスパラメーター (m=16、ef_construction=64、ef_search=40) を使用しないでください。

付録 I: RDS for PostgreSQL: インデックス構築へのパラメーター影響

この付録では、ann-benchmarks のテスト結果を使用して、RDS for PostgreSQL およびベクトル関連の各種パラメーターがインデックス構築に与える影響を示します。

RDS for PostgreSQL: インデックス構築へのパラメーター影響

たとえば、ann-benchmarks のテストパラメーターが m=16efConstruction=64 に設定されている場合、RDS for PostgreSQL のパラメーターはインデックス構築に次のように影響します。

  • maintenance_work_mem

    このパラメーターは、VACUUMCREATE INDEX などのメンテナンス操作で使用できる最大メモリ量 (KB) を指定します。maintenance_work_mem の値がデータセットサイズ未満の場合、値を増やすとインデックス構築時間が短縮されます。ただし、値がデータセットサイズを超えると、それ以上構築時間は短縮されません。

    たとえば、pg.x8.2xlarge.2c (16 コア、128 GB) タイプの RDS for PostgreSQL インスタンスで、max_parallel_maintenance_workers パラメーターをデフォルト値の 8 に設定し、nytimes-256-angular データセット (約 324 MB) を使用した場合、maintenance_work_mem パラメーターはインデックス構築に次のように影響します。

    maintenance_work_mem

    インデックス構築時間 (秒)

    64 MB (65536 KB)

    52.82

    128 MB (131072 KB)

    46.79

    256 MB (262144 KB)

    36.40

    512 MB (524288 KB)

    18.90

    1 GB (1048576 KB)

    19.06

  • max_parallel_maintenance_workers

    このパラメーターは、CREATE INDEX で使用されるパラレルワーカーの最大数を設定します。max_parallel_maintenance_workers を増やすと、インデックス構築時間が短縮されます。

    たとえば、pg.x8.2xlarge.2c (16 コア、128 GB) タイプの RDS for PostgreSQL インスタンスで、maintenance_work_mem パラメーターを 2 GB (2048 MB) に設定し、nytimes-256-angular データセット (約 324 MB) を使用した場合、max_parallel_maintenance_workers パラメーターはインデックス構築に次のように影響します。

    max_parallel_maintenance_workers

    インデックス構築時間 (秒)

    1

    76.00

    2

    51.34

    4

    32.49

    8

    19.66

    12

    14.44

    16

    13.07

    24

    13.15

ベクトルパラメーターのインデックス構築への影響

RDS for PostgreSQL のパラメーターを maintenance_work_mem=8 GB (8388608 KB)max_parallel_maintenance_workers=16 に設定した場合、以下のセクションではベクトルパラメーターがインデックス構築に与える影響を示します。

  • ベクトルディメンション

    以下のテストでは、GloVe データセット (1,183,514 ベクター) を使用し、ann-benchmarks のテストパラメーターを m=16efConstruction=64ef_search=40 に設定しています。結果からベクトルディメンションが大きくなるほど、インデックス構築時間およびクエリ遅延が増加し、取得率および QPS は低下することがわかります。

    ディメンション

    構築時間 (秒)

    再現率

    QPS

    p99 (ms)

    25

    195.10

    0.99985

    192.94

    7.84

    50

    236.92

    0.99647

    152.36

    9.69

    100

    319.36

    0.97231

    126.89

    11.14

    200

    529.33

    0.93186

    95.05

    15.11

    説明

    クエリ遅延の 99 パーセンタイルを示します。つまり、99% のクエリリクエストはこの値より短い時間で完了し、残り 1% のみがより長い時間を要します。

  • ベクター数

    これらのテストでは、dbpedia-openai-{n}k-angular データセットシリーズを使用します。ここで n はベクター数を千単位で表します (100 ~ 1,000)。ann-benchmarks のテストパラメーターを m=48efConstruction=256ef_search=200 に設定した場合のテスト結果は次のとおりです。結果からベクター数が増加するにつれてインデックス構築時間が非線形的に増加し、取得率および QPS は低下し、クエリ遅延が増加することがわかります。

    ベクター数

    行数 (×10,000)

    構築時間 (秒)

    再現率

    QPS

    p99 (ms)

    100

    10

    54.05

    0.9993

    171.74

    8.93

    200

    20

    137.23

    0.99901

    146.78

    10.81

    500

    50

    436.68

    0.999

    118.55

    13.94

    1000

    100

    957.26

    0.99879

    101.60

    16.35

付録 II: カスタムテストデータセット

以下の例では、nytimes-256-angular データ形式に基づくデータセットの作成方法を示します。

  1. 次のスクリプトを実行して、カスタムテストデータセットを作成します。

    説明

    この例では、rds_ai 拡張が必要です。詳細については、「AI (rds_ai)」をご参照ください。

    import h5py
    import numpy as np
    import psycopg2
    import pgvector.psycopg2
    
    # 接続情報
    conn_info = {
        'host': 'pgm-****.rds.aliyuncs.com',
        'user': 'ann_testuser',
        'password': '****',
        'port': '5432',
        'dbname': 'ann_testdb'
    }
    
    embedding_len = 1024
    distance_top_n = 100
    query_batch_size = 100
    
    try:
        # RDS for PostgreSQL データベースに接続
        with psycopg2.connect(**conn_info) as connection:
            pgvector.psycopg2.register_vector(connection)
            with connection.cursor() as cur:
                # ベクトルデータを取得
                cur.execute("select count(1) from test_rag")
                count = cur.fetchone()[0]
    
                train_embeddings = []
                for start in range(0, count, query_batch_size):
                    query = f"SELECT embedding FROM test_rag ORDER BY id OFFSET {start} LIMIT {query_batch_size}"
                    cur.execute(query)
                    res = [embedding[0] for embedding in cur.fetchall()]
                    train_embeddings.extend(res)
                train = np.array(train_embeddings)
    
                # クエリデータを取得し、埋め込みを計算
                with open('query.txt', 'r', encoding='utf-8') as file:
                    queries = [query.strip() for query in file]
                test = []
                # rds_ai 拡張をインストールするか、Alibaba Cloud Model Studio SDK を使用
                for query in queries:
                    cur.execute(f"SELECT rds_ai.embed('{query.strip()}')::vector(1024)")
                    test.extend([cur.fetchone()[0]])
                test = np.array(test)
    
        # Top N 最近傍距離を計算
        dot_product = np.dot(test, train.T)
        norm_test = np.linalg.norm(test, axis=1, keepdims=True)
        norm_train = np.linalg.norm(train, axis=1, keepdims=True)
        similarity = dot_product / (norm_test * norm_train.T)
        distance_matrix = 1 - similarity
    
        neighbors = np.argsort(distance_matrix, axis=1)[:, :distance_top_n]
        distances = np.take_along_axis(distance_matrix, neighbors, axis=1)
    
        with h5py.File('custom_dataset.hdf5', 'w') as f:
            f.create_dataset('distances', data=distances)
            f.create_dataset('neighbors', data=neighbors)
            f.create_dataset('test', data=test)
            f.create_dataset('train', data=train)
            f.attrs.update({
                "type": "dense",
                "distance": "angular",
                "dimension": embedding_len,
                "point_type": "float"
            })
    
        print("HDF5 ファイルが正常に作成され、データセットが追加されました。")
    
    except (Exception, psycopg2.DatabaseError) as error:
        print(f"エラー: {error}")
    
  2. ~/ann-benchmarks/ann_benchmarks/datasets.py ファイルの DATASETS セクションにカスタムテストデータセットを登録します。

    DATASETS: Dict[str, Callable[[str], None]] = {
      ......,
      "<custom_dataset>": None,
    }
  3. カスタムテストデータセットを ~/ann-benchmarks ディレクトリにアップロードします。その後、run.py テストスクリプトでデータセットを使用できます。