All Products
Search
Document Center

ApsaraDB RDS:Gunakan PASE untuk pencarian vektor yang efisien

Last Updated:Aug 22, 2026
Penting

PASE tidak lagi dipelihara. Gunakan ekstensi pgvector sebagai gantinya. Untuk detailnya, lihat Gunakan ekstensi pgvector untuk melakukan pencarian kemiripan vektor berdimensi tinggi.

PASE (PostgreSQL ANN search extension) menambahkan kemampuan pencarian approximate nearest neighbor (ANN) ke ApsaraDB RDS for PostgreSQL dengan menggunakan dua algoritma indeks: IVFFlat dan Hierarchical Navigable Small World (HNSW).

PASE melakukan pencarian kemiripan pada vektor yang sudah ada. Ekstensi ini tidak mengekstraksi atau menghasilkan vektor fitur — Anda harus menyediakannya sendiri.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

  • Instans ApsaraDB RDS for PostgreSQL yang menjalankan PostgreSQL 11 atau versi lebih baru (PostgreSQL 17 tidak didukung)

  • Akun istimewa untuk menjalankan pernyataan SQL dalam topik ini

Pilih algoritma indeks

Kedua algoritma tersebut menukar waktu pembuatan dan penggunaan memori dengan recall kueri. Gunakan tabel berikut untuk memutuskan:

IVFFlat HNSW
Cara kerja Mempartisi vektor ke dalam kluster; mengkueri subset kluster yang dekat dengan target Membangun graf kedekatan multi-lapis; menjelajah dari lapisan kasar ke lapisan halus
Paling cocok untuk Kueri presisi tinggi di mana latensi hingga 100 ms masih dapat diterima Dataset besar (puluhan juta vektor) di mana tanggapan harus tiba dalam waktu kurang dari 10 ms
Recall 100% mungkin? Ya, ketika vektor kueri berada dalam dataset kandidat Presisi mencapai batas maksimum setelah tingkat tertentu dan tidak dapat ditingkatkan hanya dengan menyesuaikan parameter
Waktu pembuatan Cepat Lambat
Penyimpanan Rendah Lebih tinggi (menyimpan tetangga graf kedekatan)
Data diperlukan sebelum pengindeksan? Ya, saat menggunakan pengelompokan internal (clustering_type = 1) — memerlukan data untuk langkah pelatihan k-means Tidak

Gunakan IVFFlat untuk perbandingan gambar dan workload presisi tinggi lainnya di mana latensi kueri yang sedikit lebih tinggi masih dapat diterima.

Gunakan HNSW untuk sistem rekomendasi dan pencarian semantik berskala besar, di mana latensi rendah lebih penting daripada recall sempurna.

Cara kerja

IVFFlat

IVFFlat adalah versi yang disederhanakan dari algoritma IVFADC.

IVFFlat algorithm
  1. IVFFlat menggunakan k-means untuk membagi vektor ke dalam kluster. Setiap kluster memiliki pusat (centroid).

  2. Algoritma ini menemukan n centroid terdekat dengan vektor kueri.

  3. Algoritma ini mencari semua vektor dalam n kluster tersebut dan mengembalikan k hasil terdekat.

Mengabaikan kluster yang jauh mempercepat kueri tetapi dapat mengurangi recall — vektor yang mirip dengan kueri mungkin berada di luar kluster yang dipilih. Nilai n yang lebih besar meningkatkan recall dengan biaya komputasi yang lebih tinggi.

IVFFlat berbeda dari IVFADC pada fase kedua. IVFADC menggunakan kuantisasi produk untuk menghindari traversal brute-force, yang lebih cepat tetapi kurang presisi. IVFFlat menggunakan pencarian brute-force dalam kluster yang dipilih, memberi Anda kendali langsung atas pertukaran antara presisi dan kecepatan.

HNSW

HNSW adalah algoritma ANN berbasis graf.

HNSW algorithm
  1. HNSW membangun struktur hierarkis berupa lapisan (graf). Setiap lapisan merupakan representasi kasar dari lapisan di bawahnya.

  2. Pencarian dimulai dari elemen acak di lapisan paling atas.

  3. HNSW menemukan tetangga elemen saat ini, menambahkannya ke daftar kandidat berukuran tetap yang diurutkan berdasarkan jarak, lalu terus memperluas tetangga. Ketika daftar stabil, elemen teratas menjadi titik masuk untuk lapisan berikutnya di bawahnya.

  4. Proses ini diulang hingga lapisan paling bawah dicari.

HNSW menggunakan algoritma Navigable Small World (NSW) — awalnya dirancang untuk graf satu lapis — untuk membangun setiap lapisan, sehingga memungkinkan traversal lebih cepat dibanding metode berbasis pengelompokan.

Pengetahuan dasar tentang pembelajaran mesin dan algoritma pencarian ANN diasumsikan telah dimiliki pembaca dalam seluruh topik ini.

Siapkan PASE

Langkah 1: Aktifkan ekstensi

CREATE EXTENSION pase;

Langkah 2: Hitung kemiripan vektor (uji coba cepat opsional)

Gunakan operator <?> untuk menghitung kemiripan antara dua vektor sebelum membuat indeks.

Konstruksi tipe PASE:

SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[]) AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[], 0) AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[], 0, 1) AS distance;

Konstruksi berbasis string:

SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1'::pase AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1:0'::pase AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1:0:1'::pase AS distance;

Operator <?> menerima float4[] di sisi kiri dan nilai PASE di sisi kanan. Kedua vektor harus memiliki jumlah dimensi yang sama, atau PASE akan mengembalikan error perhitungan kemiripan.

Dalam konstruktor PASE (float4[], second_param, similarity_method):

  • Parameter kedua: dicadangkan; atur ke 0

  • Metode kemiripan: 0 = Jarak Euclidean, 1 = dot product (juga disebut inner product)

Jika menggunakan metode dot product atau cosine similarity, normalisasi vektor input terlebih dahulu. Vektor yang dinormalisasi memenuhi sehingga . Untuk vektor yang dinormalisasi, dot product sama dengan nilai cosinus. ApsaraDB RDS for PostgreSQL mendukung metode Jarak Euclidean secara langsung; gunakan metode dot product hanya setelah menormalisasi vektor.

Langkah 3: Buat indeks

Indeks IVFFlat

CREATE INDEX ivfflat_idx ON table_name
USING
  pase_ivfflat(column_name)
WITH
  (clustering_type = 1, distance_type = 0, dimension = 256, base64_encoded = 0, clustering_params = "10,100");

Parameter:

Parameter Wajib Bawaan Deskripsi
clustering_type Ya Metode pengelompokan. 0 = eksternal (memuat file centroid yang ditentukan oleh clustering_params). 1 = k-means internal. Mulailah dengan 1 jika Anda baru mengenal PASE.
distance_type Tidak 0 Metode kemiripan. 0 = Jarak Euclidean. 1 = dot product (memerlukan vektor yang dinormalisasi; urutan dot product berlawanan dengan urutan Euclidean). ApsaraDB RDS for PostgreSQL hanya mendukung Jarak Euclidean secara langsung.
dimension Ya Jumlah dimensi vektor. Maksimum: 512.
base64_encoded Tidak 0 Enkode vektor. 0 = float4[]. 1 = float[] yang dienkode Base64.
clustering_params Ya Untuk pengelompokan internal (clustering_type = 1): "sampling_ratio,k". sampling_ratio adalah fraksi pengambilan sampel dengan penyebut 1000, rentang (0, 1000] — nilai 1 berarti pengambilan sampel dengan rasio 1:1000 sebelum menjalankan k-means; pastikan total catatan yang diambil sampelnya tidak melebihi 100.000. k adalah jumlah centroid; gunakan nilai dalam rentang [100, 1000]. Untuk pengelompokan eksternal (clustering_type = 0): jalur direktori file centroid.

Indeks HNSW

CREATE INDEX hnsw_idx ON table_name
USING
  pase_hnsw(column_name)
WITH
  (dim = 256, base_nb_num = 16, ef_build = 40, ef_search = 200, base64_encoded = 0);

Parameter:

Parameter Wajib Nilai valid Deskripsi
dim Ya [8, 512] Jumlah dimensi vektor.
base_nb_num Ya Direkomendasikan: [16, 128] Jumlah tetangga yang disimpan per elemen. Nilai lebih tinggi meningkatkan recall tetapi menambah waktu pembuatan dan penyimpanan.
ef_build Ya Direkomendasikan: [40, 400] Ukuran heap kandidat selama pembuatan indeks. Nilai lebih tinggi meningkatkan recall tetapi memperlambat pembuatan.
ef_search Ya [10, 400] Ukuran heap kandidat selama kueri. Nilai lebih tinggi meningkatkan recall tetapi mengurangi throughput kueri.
base64_encoded Tidak 0 atau 1 Enkode vektor. 0 = float4[]. 1 = float[] yang dienkode Base64.

Langkah 4: Kueri vektor

Kueri IVFFlat

Gunakan operator <#> dan sertakan ORDER BY — indeks hanya berlaku jika menggunakan ORDER BY.

SELECT id, vector <#> '1,1,1'::pase AS distance
FROM table_name
ORDER BY
  vector <#> '1,1,1:10:0'::pase
ASC LIMIT 10;

Format string kueri adalah vector:n:similarity_method:

  • `n`: jumlah kluster yang akan dicari, rentang (0, 1000]. Nilai lebih tinggi meningkatkan recall dengan biaya kecepatan. Sesuaikan berdasarkan kebutuhan recall dan latensi Anda.

  • `similarity_method`: 0 = Jarak Euclidean, 1 = dot product (memerlukan vektor yang dinormalisasi).

Kueri HNSW

Gunakan operator <?> dan sertakan ORDER BY.

SELECT id, vector <?> '1,1,1'::pase AS distance
FROM table_name
ORDER BY
  vector <?> '1,1,1:100:0'::pase
ASC LIMIT 10;

Format string kueri adalah vector:ef:similarity_method:

  • `ef`: ukuran heap kandidat selama kueri, rentang (0, ∞). Mulailah dari 40 dan tingkatkan secara bertahap hingga menemukan keseimbangan yang tepat untuk workload Anda.

  • `similarity_method`: 0 = Jarak Euclidean, 1 = dot product (memerlukan vektor yang dinormalisasi).

Catatan penggunaan

  • Pembengkakan indeks: Periksa ukuran indeks dengan SELECT pg_relation_size('index_name'); dan bandingkan dengan ukuran tabel. Jika indeks lebih besar dari tabel dan kueri melambat, bangun ulang indeks tersebut.

  • Deviasi akurasi setelah pembaruan data: Pembaruan data yang sering dapat menyebabkan indeks menjadi usang. Jika recall 100% diperlukan, bangun ulang indeks secara berkala.

  • Membuat indeks IVFFlat dengan centroid internal: Atur clustering_type = 1 dan pastikan tabel sudah berisi data sebelum membuat indeks.

Contoh: Alur lengkap IVFFlat

Contoh ini membuat tabel, memuat vektor berdimensi 3, membangun indeks IVFFlat, dan menjalankan kueri tetangga terdekat.

-- Langkah 1: Aktifkan ekstensi
CREATE EXTENSION pase;

-- Langkah 2: Buat tabel
CREATE TABLE vectors_table (
  id     SERIAL PRIMARY KEY,
  vector float4[] NOT NULL
);

-- Langkah 3: Masukkan data sampel
INSERT INTO vectors_table (vector) VALUES
  ('{1.0, 0.0, 0.0}'),
  ('{0.0, 1.0, 0.0}'),
  ('{0.0, 0.0, 1.0}'),
  ('{0.0, 0.5, 0.0}'),
  ('{0.0, 0.5, 0.0}'),
  ('{0.0, 0.6, 0.0}'),
  ('{0.0, 0.7, 0.0}'),
  ('{0.0, 0.8, 0.0}'),
  ('{0.0, 0.0, 0.0}');

-- Langkah 4: Bangun indeks IVFFlat
CREATE INDEX ivfflat_idx ON vectors_table
USING
  pase_ivfflat(vector)
WITH
  (clustering_type = 1, distance_type = 0, dimension = 3, base64_encoded = 0, clustering_params = "10,100");

-- Langkah 5: Kueri 10 tetangga terdekat dari [1, 1, 1]
SELECT id, vector <#> '1,1,1'::pase AS distance
FROM vectors_table
ORDER BY
  vector <#> '1,1,1:10:0'::pase
ASC LIMIT 10;

Lampiran

Hitung dot product atau cosine similarity

Dot product dari vektor yang dinormalisasi sama dengan nilai cosinusnya. Fungsi ini menggunakan indeks HNSW untuk mengambil hasil top-k berdasarkan dot product:

CREATE OR REPLACE FUNCTION inner_product_search(
  query_vector text,
  ef          integer,
  k           integer,
  table_name  text
)
RETURNS TABLE (id integer, uid text, distance float4) AS $$
BEGIN
  RETURN QUERY EXECUTE format('
    SELECT a.id, a.vector <?> pase(ARRAY[%s], %s, 1) AS distance
    FROM (
      SELECT id, vector
      FROM %s
      ORDER BY vector <?> pase(ARRAY[%s], %s, 0) ASC
      LIMIT %s
    ) a
    ORDER BY distance DESC;',
    query_vector, ef, table_name, query_vector, ef, k
  );
END
$$ LANGUAGE plpgsql;

Gunakan file centroid eksternal untuk IVFFlat

Ini adalah opsi lanjutan. Unggah file centroid eksternal ke direktori server, lalu referensikan dalam clustering_params saat clustering_type = 0. Format file tersebut adalah:

Jumlah dimensi|Jumlah centroid|Dataset vektor centroid

Contoh:

3|2|1,1,1,2,2,2

Referensi