Dokumen ini menunjukkan cara menyesuaikan indeks untuk mencapai performa kueri yang lebih cepat dan recall yang lebih baik.
Menyesuaikan indeks ScaNN
Indeks ScaNN menggunakan pengindeksan berbasis kuantisasi pohon. Dalam teknik kuantisasi pohon, indeks mempelajari hierarki penelusuran bersama dengan fungsi kuantisasi (atau hashing). Saat Anda menjalankan kueri, hierarki penelusuran digunakan untuk memangkas ruang penelusuran, sedangkan kuantisasi digunakan untuk mengompresi ukuran indeks. Pemangkasan ini mempercepat penskoran kemiripan (yaitu, jarak) antara vektor kueri dan vektor database.
Untuk mencapai kecepatan kueri per detik (QPS) yang tinggi
dan recall yang tinggi dengan kueri nearest neighbor, Anda harus mempartisi
hierarki indeks ScaNN
dengan cara yang paling sesuai untuk data
dan kueri Anda.
Sebelum membuat indeks ScaNN
, selesaikan langkah-langkah berikut:
- Pastikan tabel dengan data Anda sudah dibuat.
- Pastikan nilai yang Anda tetapkan untuk flag
maintenance_work_mem
danshared_buffers
kurang dari total memori mesin untuk menghindari masalah saat membuat indeks.
Parameter penyempurnaan
Parameter indeks dan tanda database berikut digunakan bersama untuk menemukan keseimbangan yang tepat antara recall dan QPS. Semua parameter berlaku untuk kedua jenis indeks ScaNN
.
Parameter penyesuaian | Deskripsi | Jenis parameter |
---|---|---|
num_leaves |
Jumlah partisi yang akan diterapkan ke indeks ini. Jumlah partisi yang Anda terapkan saat membuat indeks memengaruhi performa indeks. Dengan meningkatkan partisi untuk sejumlah vektor yang ditetapkan, Anda akan membuat indeks yang lebih terperinci, yang meningkatkan performa kueri dan recall. Namun, hal ini akan memperpanjang waktu pembuatan indeks. Karena hierarki tiga tingkat dibuat lebih cepat daripada hierarki dua tingkat, Anda dapat meningkatkan num_leaves_value saat membuat indeks hierarki tiga tingkat untuk mendapatkan performa yang lebih baik.
|
Pembuatan indeks |
quantizer |
Jenis quantizer yang ingin Anda gunakan untuk hierarki K-means. Nilai default-nya adalah SQ8 untuk performa kueri yang lebih baik.Tetapkan ke FLAT untuk recall yang lebih baik. |
Pembuatan indeks |
enable_pca |
Mengaktifkan Analisis Komponen Utama (PCA), yang merupakan teknik pengurangan dimensi yang digunakan untuk mengurangi ukuran penyematan secara otomatis jika memungkinkan. Opsi ini diaktifkan secara default. Tetapkan ke false jika Anda mengamati penurunan dalam recall. |
Pembuatan indeks |
scann.num_leaves_to_search |
Flag database mengontrol kompromi antara recall dan QPS. Nilai defaultnya adalah 1% dari nilai yang ditetapkan di num_leaves . Semakin tinggi nilai yang ditetapkan, semakin baik recall-nya, tetapi menghasilkan QPS yang lebih rendah, dan sebaliknya. |
Runtime kueri |
scann.max_top_neighbors_buffer_size |
Flag database menentukan ukuran cache yang digunakan untuk meningkatkan performa kueri yang difilter dengan memberi skor atau peringkat pada kandidat tetangga yang dipindai dalam memori, bukan disk. Nilai defaultnya adalah 20000 . Makin tinggi nilai yang ditetapkan, makin baik QPS dalam kueri yang difilter, tetapi akan menghasilkan penggunaan memori yang lebih tinggi, dan sebaliknya. |
Runtime kueri |
scann.pre_reordering_num_neighbors |
Tanda database saat ditetapkan, menentukan jumlah kandidat tetangga yang akan dipertimbangkan selama tahap pengurutan ulang setelah penelusuran awal mengidentifikasi sekumpulan kandidat. Tetapkan nilai ini ke nilai yang lebih tinggi dari jumlah tetangga yang ingin ditampilkan kueri. Set nilai yang lebih tinggi menghasilkan recall yang lebih baik, tetapi pendekatan ini menghasilkan QPS yang lebih rendah. |
Runtime kueri |
max_num_levels |
Jumlah maksimum level hierarki pengelompokan K-means.
|
Pembuatan indeks |
Menyesuaikan indeks ScaNN
Pertimbangkan contoh berikut untuk indeks ScaNN
dua tingkat dan tiga tingkat yang menunjukkan cara menetapkan parameter penyesuaian:
Indeks dua tingkat
SET LOCAL scann.num_leaves_to_search = 1;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 1/2)]);
Indeks tiga tingkat
SET LOCAL scann.num_leaves_to_search = 10;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 2/3)], max_num_levels = 2);
Setiap operasi penyisipan atau pembaruan pada tabel tempat indeks ScaNN
sudah
dibuat akan memengaruhi cara hierarki yang dipelajari mengoptimalkan indeks. Jika
tabel Anda rentan terhadap pembaruan atau penyisipan yang sering, sebaiknya
indeks ScaNN
yang ada diindeks ulang secara berkala untuk meningkatkan akurasi recall.
Anda dapat memantau metrik indeks untuk menentukan jumlah mutasi yang dibuat sejak indeks dibuat, lalu membuat ulang indeks. Untuk mengetahui informasi selengkapnya tentang metrik, lihat Metrik indeks vektor.
Praktik terbaik untuk penyesuaian
Berdasarkan jenis indeks ScaNN
yang ingin Anda gunakan, rekomendasi untuk menyesuaikan indeks Anda akan bervariasi. Bagian ini memberikan rekomendasi tentang cara menyesuaikan parameter indeks untuk mendapatkan keseimbangan yang optimal antara recall dan QPS.
Indeks hierarki dua tingkat
Untuk menerapkan rekomendasi guna membantu Anda menemukan nilai num_leaves
dan num_leaves_to_search
yang optimal untuk set data,
ikuti langkah-langkah berikut:
- Buat indeks
ScaNN
dengannum_leaves
ditetapkan ke akar kuadrat dari jumlah baris tabel yang diindeks. - Jalankan kueri pengujian, dengan meningkatkan nilai
scann.num_of_leaves_to_search
, hingga Anda mencapai rentang recall target–misalnya, 95%. Untuk mengetahui informasi selengkapnya tentang cara menganalisis kueri, lihat Menganalisis kueri. - Perhatikan rasio antara
scann.num_leaves_to_search
dannum_leaves
yang akan digunakan pada langkah berikutnya. Rasio ini memberikan perkiraan di sekitar set data yang akan membantu Anda mencapai target recall.
Jika Anda menggunakan vektor dimensi tinggi (500 dimensi atau lebih tinggi) dan ingin meningkatkan recall, coba sesuaikan nilaiscann.pre_reordering_num_neighbors
. Sebagai titik awal, tetapkan nilai ke100 * sqrt(K)
denganK
adalah batas yang Anda tetapkan dalam kueri. - Jika QPS Anda terlalu rendah setelah kueri mencapai recall target, ikuti langkah-langkah berikut:
- Buat ulang indeks, dengan meningkatkan nilai
num_leaves
danscann.num_leaves_to_search
sesuai panduan berikut:- Tetapkan
num_leaves
ke faktor yang lebih besar dari akar kuadrat jumlah baris Anda. Misalnya, jika indeks memilikinum_leaves
yang ditetapkan ke akar kuadrat jumlah baris, coba tetapkan ke dua kali akar kuadrat. Jika nilainya sudah dua kali lipat, coba tetapkan nilai tersebut untuk melipatgandakan akar kuadrat. - Tingkatkan
scann.num_leaves_to_search
sesuai kebutuhan untuk mempertahankan rasionya dengannum_leaves
, yang Anda catat pada Langkah 3. - Tetapkan
num_leaves
ke nilai yang kurang dari atau sama dengan jumlah baris dibagi 100.
- Tetapkan
- Jalankan lagi kueri pengujian.
Saat menjalankan kueri pengujian, lakukan eksperimen dengan mengurangi
scann.num_leaves_to_search
, menemukan nilai yang meningkatkan QPS sekaligus menjaga perolehan tetap tinggi. Coba nilaiscann.num_leaves_to_search
yang berbeda tanpa membuat ulang indeks.
- Buat ulang indeks, dengan meningkatkan nilai
- Ulangi Langkah 4 hingga QPS dan rentang recall mencapai nilai yang dapat diterima.
Indeks hierarki tiga tingkat
Selain rekomendasi untuk indeks ScaNN
hierarki dua tingkat, gunakan panduan dan langkah-langkah berikut untuk menyesuaikan indeks:
- Meningkatkan
max_num_levels
dari1
untuk hierarki dua tingkat menjadi2
untuk hierarki tiga tingkat secara signifikan mengurangi waktu untuk membuat indeks, tetapi mengorbankan akurasi recall. Tetapkanmax_num_levels
menggunakan rekomendasi berikut:- Tetapkan nilai ke
2
jika jumlah baris vektor melebihi 100 juta baris. - Tetapkan nilai ke
1
jika jumlah baris vektor kurang dari 10 juta baris. - Tetapkan ke
1
atau2
jika jumlah baris vektor berada antara 10 juta dan 100 juta baris, berdasarkan keseimbangan waktu pembuatan indeks dan akurasi recall yang Anda butuhkan.
- Tetapkan nilai ke
Untuk menerapkan rekomendasi guna menemukan nilai optimal parameter indeks num_leaves
dan max_num_levels
, ikuti langkah-langkah berikut:
Buat indeks
ScaNN
dengan kombinasinum_leaves
danmax_num_levels
berikut berdasarkan set data Anda:- baris vektor lebih dari 100 juta baris: Tetapkan
max_num_levels
sebagai2
dannum_leaves
sebagaipower(rows, ⅔)
. - baris vektor kurang dari 100 juta baris: Tetapkan
max_num_levels
sebagai1
dannum_leaves
sebagaisqrt(rows)
. - baris vektor antara 10 juta dan 100 juta baris: Mulailah dengan menetapkan
max_num_levels
sebagai1
dannum_leaves
sebagaisqrt(rows)
.
- baris vektor lebih dari 100 juta baris: Tetapkan
Jalankan kueri pengujian Anda. Untuk mengetahui informasi selengkapnya tentang cara menganalisis kueri, lihat Menganalisis kueri.
Jika waktu pembuatan indeks memuaskan, pertahankan nilai
max_num_levels
, dan bereksperimenlah dengan nilainum_leaves
untuk akurasi recall yang optimal.Jika Anda tidak puas dengan waktu pembuatan indeks, lakukan hal berikut:
Jika nilai
max_num_levels
adalah1
, hapus indeks. Buat ulang indeks dengan nilaimax_num_levels
yang ditetapkan ke2
.Jalankan kueri dan sesuaikan nilai
num_leaves
untuk akurasi recall yang optimal.Jika nilai
max_num_levels
adalah2
, hapus indeks. Buat ulang indeks dengan nilaimax_num_levels
yang sama dan sesuaikan nilainum_leaves
untuk akurasi recall yang optimal.
Menyesuaikan indeks IVF
Menyesuaikan nilai yang Anda tetapkan untuk parameter lists
, ivf.probes
, dan quantizer
dapat
membantu mengoptimalkan performa aplikasi Anda:
Parameter penyesuaian | Deskripsi | Jenis parameter |
---|---|---|
lists |
Jumlah daftar yang dibuat selama pembuatan indeks. Titik awal untuk menetapkan nilai ini adalah (rows)/1000 untuk maksimal satu juta baris, dan sqrt(rows) untuk lebih dari satu juta baris. |
Pembuatan indeks |
quantizer |
Jenis quantizer yang ingin Anda gunakan untuk hierarki K-means. Nilai defaultnya adalah SQ8 untuk performa kueri yang lebih baik. Tetapkan ke FLAT untuk recall yang lebih baik. |
Pembuatan indeks |
ivf.probes |
jumlah daftar terdekat yang akan dijelajahi selama penelusuran. Titik awal untuk nilai ini adalah sqrt(lists) . |
Runtime kueri |
Pertimbangkan contoh berikut yang menunjukkan indeks IVF
dengan parameter penyesuaian yang ditetapkan:
SET LOCAL ivf.probes = 10;
CREATE INDEX my-ivf-index ON my-table
USING ivf (vector_column cosine)
WITH (lists = 100, quantizer = 'SQ8');
Menyesuaikan indeks IVFFlat
Menyesuaikan nilai yang Anda tetapkan untuk parameter lists
dan ivfflat.probes
dapat
membantu mengoptimalkan performa aplikasi:
Parameter penyesuaian | Deskripsi | Jenis parameter |
---|---|---|
lists |
Jumlah daftar yang dibuat selama pembuatan indeks. Titik awal untuk menetapkan nilai ini adalah (rows)/1000 untuk maksimal satu juta baris, dan sqrt(rows) untuk lebih dari satu juta baris. |
Pembuatan indeks |
ivfflat.probes |
Jumlah daftar terdekat yang akan dijelajahi selama penelusuran. Titik awal untuk nilai ini adalah sqrt(lists) . |
Runtime kueri |
Sebelum mem-build indeks IVFFlat
, pastikan flag max_parallel_maintenance_workers
database Anda ditetapkan ke nilai yang memadai untuk mempercepat pembuatan indeks pada tabel besar.
Pertimbangkan contoh berikut yang menunjukkan indeks IVFFlat
dengan parameter penyesuaian yang ditetapkan:
SET LOCAL ivfflat.probes = 10;
CREATE INDEX my-ivfflat-index ON my-table
USING ivfflat (vector_column cosine)
WITH (lists = 100);
Menyesuaikan indeks HNSW
Menyesuaikan nilai yang Anda tetapkan untuk parameter m
, ef_construction
, dan hnsw.ef_search
dapat
membantu mengoptimalkan performa aplikasi.
Parameter penyesuaian | Deskripsi | Jenis parameter |
---|---|---|
m |
Jumlah maksimum koneksi per node dalam grafik. Anda dapat memulai dengan nilai default sebagai 16 (default) dan bereksperimen dengan nilai yang lebih tinggi berdasarkan ukuran set data Anda. |
Pembuatan indeks |
ef_construction |
Ukuran daftar kandidat dinamis yang dipertahankan selama konstruksi grafik, yang terus memperbarui kandidat terbaik saat ini untuk tetangga terdekat untuk node. Tetapkan nilai ini ke nilai apa pun yang lebih tinggi dari dua kali nilai m —misalnya, 64 (default). |
Pembuatan indeks |
ef_search |
Ukuran daftar kandidat dinamis yang digunakan selama penelusuran. Anda dapat mulai menetapkan nilai ini ke m atau ef_construction , lalu mengubahnya sambil mengamati recall. Nilai defaultnya adalah 40 . |
Runtime kueri |
Pertimbangkan contoh berikut yang menunjukkan indeks hnsw
dengan parameter penyesuaian yang ditetapkan:
SET LOCAL hnsw.ef_search = 40;
CREATE INDEX my-hnsw-index ON my-table
USING hnsw (vector_column cosine)
WITH (m = 16, ef_construction = 200);
Menganalisis kueri
Gunakan perintah EXPLAIN ANALYZE
untuk menganalisis insight kueri seperti yang ditunjukkan dalam contoh kueri SQL berikut.
EXPLAIN ANALYZE SELECT result-column FROM my-table
ORDER BY EMBEDDING_COLUMN ::vector
USING INDEX my-scann-index
<-> embedding('textembedding-gecko@003', 'What is a database?')
LIMIT 1;
Contoh respons QUERY PLAN
menyertakan informasi seperti waktu yang diperlukan, jumlah baris yang dipindai atau ditampilkan, dan resource yang digunakan.
Limit (cost=0.42..15.27 rows=1 width=32) (actual time=0.106..0.132 rows=1 loops=1)
-> Index Scan using my-scann-index on my-table (cost=0.42..858027.93 rows=100000 width=32) (actual time=0.105..0.129 rows=1 loops=1)
Order By: (embedding_column <-> embedding('textgecko@003', 'What is a database?')::vector(768))
Limit value: 1
Planning Time: 0.354 ms
Execution Time: 0.141 ms
Melihat metrik indeks vektor
Anda dapat menggunakan metrik indeks vektor untuk meninjau performa indeks vektor, mengidentifikasi area yang perlu ditingkatkan, dan menyesuaikan indeks berdasarkan metrik, jika diperlukan.
Untuk melihat semua metrik indeks vektor, jalankan kueri SQL berikut, yang menggunakan tampilan pg_stat_ann_indexes
:
SELECT * FROM pg_stat_ann_indexes;
Untuk informasi selengkapnya tentang daftar lengkap metrik, lihat Metrik indeks vektor.