Halaman ini menjelaskan cara menemukan perkiraan tetangga terdekat (ANN), membuat indeks vektor, dan membuat kueri embedding vektor menggunakan fungsi jarak ANN berikut di Spanner:
APPROX_COSINE_DISTANCE
APPROX_EUCLIDEAN_DISTANCE
APPROX_DOT_PRODUCT
Jika set data berukuran kecil, Anda dapat menggunakan tetangga K terdekat (KNN) untuk menemukan vektor k terdekat yang tepat. Namun, seiring bertambahnya set data Anda, latensi dan biaya penelusuran KNN juga meningkat. Anda dapat menggunakan ANN untuk menemukan perkiraan tetangga terdekat k dengan latensi dan biaya yang berkurang secara signifikan.
Perkiraan k-nearest neighbors
Dalam penelusuran ANN, vektor k yang ditampilkan bukanlah tetangga terdekat k teratas yang sebenarnya. Terkadang, beberapa vektor yang bukan termasuk dalam tetangga terdekat k teratas akan ditampilkan. Hal ini dikenal sebagai kehilangan recall. Jumlah kehilangan recall yang dapat Anda terima bergantung pada kasus penggunaan, tetapi dalam sebagian besar kasus, kehilangan sedikit recall sebagai imbalan atas peningkatan performa database adalah kompromi yang dapat diterima.
Untuk mengetahui detail selengkapnya tentang fungsi perkiraan jarak Spanner, lihat:
APPROX_COSINE_DISTANCE
di GoogleSQLAPPROX_EUCLIDEAN_DISTANCE
di GoogleSQLAPPROX_DOT_PRODUCT
di GoogleSQL
Indeks vektor
Spanner mempercepat penelusuran vektor ANN menggunakan indeks vektor khusus. Indeks ini memanfaatkan Scalable Nearest Neighbor (ScaNN) dari Google Research, algoritma nearest neighbor yang sangat efisien.
Indeks vektor menggunakan struktur berbasis hierarki untuk mempartisi data dan memfasilitasi penelusuran yang lebih cepat. Spanner menawarkan konfigurasi hierarki dua tingkat dan tiga tingkat:
- Konfigurasi hierarki dua tingkat: Node daun (
num_leaves
) berisi grup vektor yang terkait erat beserta centroid yang sesuai. Level root terdiri dari centroid dari semua node daun. - Konfigurasi hierarki tiga tingkat: Konsepnya mirip dengan hierarki dua tingkat, sekaligus
memperkenalkan lapisan cabang tambahan (
num_branches
), yang centroid node daunnya dipartisi lebih lanjut untuk membentuk tingkat root (num_leaves
).
Selain itu, Anda harus membuat indeks vektor dengan metrik jarak tertentu.
Anda dapat memilih metrik jarak yang paling sesuai untuk kasus penggunaan Anda dengan menetapkan distance_type
ke salah satu dari COSINE
, DOT_PRODUCT
, atau EUCLIDEAN
.
Untuk mengetahui informasi selengkapnya, lihat pernyataan VECTOR INDEX
.
Batasan
Indeks vektor Spanner memiliki batasan berikut:
ALTER VECTOR INDEX
tidak didukung.
Membuat indeks vektor
Untuk mengoptimalkan indeks vektor dengan sebaik mungkin untuk recall dan performa yang baik, sebaiknya buat indeks vektor setelah sebagian besar baris dengan penyematan ditulis ke database Anda. Anda mungkin juga perlu membangun ulang indeks vektor secara berkala setelah memasukkan data baru. Untuk informasi selengkapnya, lihat Mem-build ulang indeks vektor.
Untuk membuat indeks vektor dengan hierarki dua tingkat dan 1.000 node daun di
tabel Documents
dengan kolom penyematan DocEmbedding
menggunakan jarak
kosinus:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding)
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Untuk membuat indeks vektor dengan hierarki tiga tingkat dan 1.000.000 node daun:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Jika kolom penyematan bersifat nullable, Anda harus mendeklarasikannya dengan
klausa WHERE column_name IS NOT NULL
:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Membuat kueri embedding vektor
Untuk membuat kueri indeks vektor, gunakan salah satu dari tiga fungsi jarak perkiraan:
APPROX_COSINE_DISTANCE
APPROX_EUCLIDEAN_DISTANCE
APPROX_DOT_PRODUCT
Batasan saat menggunakan fungsi perkiraan jarak mencakup hal-hal berikut:
- Anda harus memberikan petunjuk kueri untuk menggunakan indeks vektor.
- Anda harus menggunakan ekspresi konstan sebagai salah satu argumen fungsi jarak (misalnya, parameter atau literal).
- Kueri atau subkueri tempat fungsi jarak perkiraan digunakan harus menggunakan bentuk tertentu: fungsi jarak harus menjadi satu-satunya kunci
ORDER BY
, dan batas harus ditentukan.
Untuk daftar batasan mendetail, lihat halaman referensi fungsi perkiraan jarak.
Contoh
Untuk menelusuri 100 vektor terdekat ke [1.0, 2.0, 3.0]
:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Jika kolom penyematan nullable:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
WHERE NullableDocEmbedding IS NOT NULL
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Praktik terbaik
Ikuti praktik terbaik berikut untuk mengoptimalkan indeks vektor dan meningkatkan hasil kueri.
Menyesuaikan opsi penelusuran vektor
Nilai penelusuran vektor yang paling optimal bergantung pada kasus penggunaan, set data vektor, dan vektor kueri. Anda mungkin perlu melakukan penyesuaian berulang untuk menemukan nilai terbaik untuk workload tertentu.
Berikut adalah beberapa panduan bermanfaat yang harus diikuti saat memilih nilai yang sesuai:
tree_depth
(tingkat hierarki): Jika tabel yang diindeks memiliki kurang dari 10 juta baris, gunakantree_depth
dari2
. Jika tidak,tree_depth
dari3
mendukung tabel hingga sekitar 10 miliar baris.num_leaves
: Gunakan akar kuadrat dari jumlah baris dalam set data. Nilai yang lebih besar dapat meningkatkan waktu build indeks vektor. Hindari menyetelnum_leaves
lebih besar daritable_row_count/1000
karena hal ini akan menghasilkan daun yang terlalu kecil dan performa yang buruk.num_leaves_to_search
: Opsi ini menentukan jumlah node daun indeks yang ditelusuri. Meningkatkannum_leaves_to_search
akan meningkatkan recall, tetapi juga meningkatkan latensi dan biaya. Sebaiknya gunakan angka yang merupakan 1% dari jumlah total daun yang ditentukan dalam pernyataanCREATE VECTOR INDEX
sebagai nilai untuknum_leaves_to_search
. Jika Anda menggunakan klausa filter, tingkatkan nilai ini untuk memperluas penelusuran.
Jika perolehan yang dapat diterima tercapai, tetapi biaya kueri terlalu tinggi,
sehingga menghasilkan QPS maksimum yang rendah, coba tingkatkan num_leaves
dengan mengikuti
langkah-langkah berikut:
- Tetapkan
num_leaves
ke beberapa kelipatan k dari nilai aslinya (misalnya,2 * sqrt(table_row_count)
). - Tetapkan
num_leaves_to_search
ke kelipatan k yang sama dengan nilai aslinya. - Lakukan eksperimen dengan mengurangi
num_leaves_to_search
untuk meningkatkan biaya dan QPS sekaligus mempertahankan recall.
Meningkatkan daya ingat
Ada beberapa kemungkinan penyebab penurunan kualitas recall, termasuk yang berikut:
num_leaves_to_search
terlalu kecil: Anda mungkin merasa lebih sulit untuk menemukan tetangga terdekat untuk beberapa vektor kueri, sehingga meningkatkannum_leaves_to_search
untuk menelusuri lebih banyak daun dapat membantu meningkatkan recall. Kueri terbaru mungkin telah bergeser untuk berisi lebih banyak vektor yang menantang ini.Indeks vektor perlu dibuat ulang: Struktur hierarki indeks vektor dioptimalkan untuk set data pada saat pembuatan, dan bersifat statis setelahnya. Oleh karena itu, jika vektor yang berbeda secara signifikan ditambahkan setelah membuat indeks vektor awal, struktur hierarki mungkin kurang optimal, sehingga menyebabkan recall yang lebih buruk.
Mem-build ulang indeks vektor
Untuk mem-build ulang indeks vektor tanpa periode nonaktif:
- Buat indeks vektor baru pada kolom penyematan yang sama dengan indeks vektor
saat ini, perbarui parameter (misalnya,
OPTIONS
) sebagaimana mestinya. - Setelah pembuatan indeks selesai, ubah petunjuk
FORCE_INDEX
agar mengarah ke indeks baru untuk memperbarui kueri penelusuran vektor. Hal ini memastikan kueri menggunakan indeks vektor baru. (Anda mungkin juga perlu menyesuaikannum_leaves_to_search
dalam kueri baru). - Hapus indeks vektor yang sudah tidak berlaku.
Langkah selanjutnya
Pelajari lebih lanjut fungsi
APPROXIMATE_COSINE_DISTANCE()
,APPROXIMATE_EUCLIDEAN_DISTANCE()
,APPROXIMATE_DOT_PRODUCT()
GoogleSQL.Pelajari pernyataan
VECTOR INDEX
GoogleSQL lebih lanjut.