Mengelola indeks vektor
Dokumen ini menjelaskan cara membuat dan mengelola indeks vektor untuk mempercepat penelusuran vektor Anda.
Indeks vektor adalah struktur data yang dirancang untuk memungkinkan
fungsi VECTOR_SEARCH
dijalankan secara lebih efisien, terutama pada set data besar.
Saat menggunakan indeks, VECTOR_SEARCH
menggunakan algoritma
Approximate Nearest Neighbor (ANN)
untuk mengurangi latensi kueri dan biaya komputasi. Meskipun ANN memperkenalkan
tingkat perkiraan, yang berarti bahwa
recall
mungkin tidak 100%, peningkatan performa biasanya menawarkan keunggulan
untuk sebagian besar aplikasi.
Peran dan izin
Untuk membuat indeks vektor, Anda memerlukan
izin IAM bigquery.tables.createIndex
pada tabel tempat Anda membuat indeks. Untuk menghapus indeks vektor, Anda memerlukan
izin bigquery.tables.deleteIndex
. Setiap peran IAM yang telah ditetapkan berikut
menyertakan izin yang diperlukan untuk menggunakan
indeks vektor:
- BigQuery Data Owner (
roles/bigquery.dataOwner
) - BigQuery Data Editor (
roles/bigquery.dataEditor
)
Memilih jenis indeks vektor
BigQuery menawarkan dua jenis indeks vektor, IVF dan TreeAH, yang masing-masing mendukung kasus penggunaan yang berbeda. BigQuery mendukung pengelompokan untuk penelusuran
vektor dengan memproses beberapa baris data input dalam
fungsi VECTOR_SEARCH
.
Untuk batch kueri kecil, indeks IVF lebih disukai. Untuk batch kueri besar,
indeks TreeAH, yang dibuat dengan
algoritma ScaNN Google,
lebih disukai.
Indeks IVF
IVF adalah indeks file terbalik, yang menggunakan algoritma k-means untuk mengelompokkan
data vektor, lalu mempartisi data vektor berdasarkan cluster tersebut. Fungsi VECTOR_SEARCH
dapat menggunakan partisi ini untuk mengurangi jumlah data yang perlu dibaca untuk menentukan hasil.
Indeks TreeAH
Jenis indeks TreeAH dinamai karena kombinasi struktur seperti pohon dan penggunaan Asymmetric Hashing (AH), teknik kuantisasi inti dari algoritma ScaNN yang mendasarinya. Indeks TreeAH berfungsi sebagai berikut:
- Tabel dasar dibagi menjadi beberapa shard yang lebih kecil dan lebih mudah dikelola.
- Model pengelompokan dilatih, dengan jumlah cluster yang berasal dari opsi
leaf_node_embedding_count
dalam argumentree_ah_options
pernyataanCREATE VECTOR INDEX
. - Vektor dikompresi dengan kuantisasi produk, yaitu teknik yang mengurangi penggunaan memorinya. Vektor yang dikompresi kemudian disimpan dalam tabel indeks, bukan vektor asli, sehingga mengurangi ukuran indeks vektor.
- Saat fungsi
VECTOR_SEARCH
berjalan, daftar kandidat untuk setiap vektor kueri dihitung secara efisien menggunakan hashing asimetris, yang dioptimalkan hardware untuk penghitungan perkiraan jarak. Kemudian, kandidat ini akan diberi skor ulang dan diberi peringkat ulang menggunakan penyematan yang sama persis.
Algoritma TreeAH dioptimalkan untuk kueri batch yang memproses ratusan atau lebih vektor kueri. Penggunaan kuantisasi produk dapat secara signifikan mengurangi latensi dan biaya, yang berpotensi dengan urutan magnitudo dibandingkan dengan IVF. Namun, karena overhead yang meningkat, algoritma IVF mungkin lebih baik jika Anda memiliki jumlah vektor kueri yang lebih kecil.
Sebaiknya coba jenis indeks TreeAH jika kasus penggunaan Anda memenuhi kriteria berikut:
Tabel Anda berisi 200 juta baris atau kurang.
Anda sering kali menjalankan kueri batch besar yang melibatkan ratusan atau lebih vektor kueri.
Untuk kueri batch kecil dengan jenis indeks TreeAH, VECTOR_SEARCH
mungkin
kembali ke
penelusuran brute force.
Jika hal ini terjadi, IndexUnusedReason
akan diberikan untuk menjelaskan alasan indeks vektor tidak digunakan.
Membuat indeks vektor IVF
Untuk membuat indeks vektor IVF, gunakan pernyataan bahasa definisi data (DDL)
CREATE VECTOR INDEX
:
Buka halaman BigQuery.
Di editor kueri, jalankan pernyataan SQL berikut:
Untuk membuat indeks vektor IVF:
CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME ON DATASET_NAME.TABLE_NAME(COLUMN_NAME) STORING(STORED_COLUMN_NAME [, ...]) OPTIONS(index_type = 'IVF', distance_type = 'DISTANCE_TYPE', ivf_options = '{"num_lists":NUM_LISTS}')
Ganti kode berikut:
INDEX_NAME
: nama indeks vektor yang Anda buat. Karena indeks selalu dibuat dalam project dan set data yang sama dengan tabel dasar, Anda tidak perlu menentukannya dalam nama.DATASET_NAME
: nama set data yang berisi tabel.TABLE_NAME
: nama tabel yang berisi kolom dengan data penyematan.COLUMN_NAME
: nama kolom yang berisi data penyematan. Kolom harus memiliki jenisARRAY<FLOAT64>
. Kolom tidak boleh memiliki kolom turunan. Semua elemen dalam array harus bukanNULL
, dan semua nilai dalam kolom harus memiliki dimensi array yang sama.STORED_COLUMN_NAME
: nama kolom tingkat teratas dalam tabel yang akan disimpan dalam indeks vektor. Jenis kolom tidak bolehRANGE
. Kolom tersimpan tidak digunakan jika tabel memiliki kebijakan akses tingkat baris atau kolom memiliki tag kebijakan. Untuk informasi tentang cara mengaktifkan kolom tersimpan, lihat Menyimpan kolom dan pra-filter.DISTANCE_TYPE
: menentukan jenis jarak default yang akan digunakan saat melakukan penelusuran vektor menggunakan indeks ini. Nilai yang didukung adalahEUCLIDEAN
,COSINE
, danDOT_PRODUCT
.EUCLIDEAN
adalah defaultnya.Pembuatan indeks itu sendiri selalu menggunakan jarak
EUCLIDEAN
untuk pelatihan, tetapi jarak yang digunakan dalam fungsiVECTOR_SEARCH
dapat berbeda.Jika Anda menentukan nilai untuk argumen
distance_type
dari fungsiVECTOR_SEARCH
, nilai tersebut akan digunakan, bukan nilaiDISTANCE_TYPE
.NUM_LISTS
: nilaiINT64
yang menentukan jumlah daftar yang dikelompokkan indeks IVF, lalu mempartisi data vektor Anda. Nilai ini harus 5.000 atau kurang. Selama pengindeksan, vektor ditetapkan ke daftar yang sesuai dengan centroid cluster terdekatnya. Jika Anda menghilangkan argumen ini, BigQuery akan menentukan nilai default berdasarkan karakteristik data Anda. Nilai default berfungsi dengan baik untuk sebagian besar kasus penggunaan.NUM_LISTS
mengontrol perincian penyesuaian kueri. Nilai yang lebih tinggi akan membuat lebih banyak daftar, sehingga Anda dapat menetapkan opsifraction_lists_to_search
dari fungsiVECTOR_SEARCH
untuk memindai persentase indeks yang lebih kecil. Misalnya, memindai 1% dari 100 daftar, bukan memindai 10% dari 10 daftar. Hal ini memungkinkan kontrol yang lebih baik terhadap kecepatan dan recall penelusuran, tetapi sedikit meningkatkan biaya pengindeksan. Tetapkan nilai argumen ini berdasarkan seberapa akurat Anda perlu menyesuaikan cakupan kueri.
Contoh berikut membuat indeks vektor pada kolom embedding
dari my_table
:
CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>); CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) OPTIONS(index_type = 'IVF');
Contoh berikut membuat indeks vektor pada kolom embedding
dari my_table
, dan menentukan jenis jarak yang akan digunakan serta opsi IVF:
CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>); CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) OPTIONS(index_type = 'IVF', distance_type = 'COSINE', ivf_options = '{"num_lists": 2500}')
Membuat indeks vektor TreeAH
Untuk membuat indeks vektor TreeAH, gunakan pernyataan bahasa definisi data (DDL)
CREATE VECTOR INDEX
:
Buka halaman BigQuery.
Di editor kueri, jalankan pernyataan SQL berikut:
CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME ON DATASET_NAME.TABLE_NAME(COLUMN_NAME) STORING(STORED_COLUMN_NAME [, ...]) OPTIONS(index_type = 'TREE_AH', distance_type = 'DISTANCE_TYPE', tree_ah_options = '{"leaf_node_embedding_count":LEAF_NODE_EMBEDDING_COUNT, "normalization_type":"NORMALIZATION_TYPE"}')
Ganti kode berikut:
INDEX_NAME
: nama indeks vektor yang Anda buat. Karena indeks selalu dibuat dalam project dan set data yang sama dengan tabel dasar, Anda tidak perlu menentukannya dalam nama.DATASET_NAME
: nama set data yang berisi tabel.TABLE_NAME
: nama tabel yang berisi kolom dengan data penyematan.COLUMN_NAME
: nama kolom yang berisi data penyematan. Kolom harus memiliki jenisARRAY<FLOAT64>
. Kolom tidak boleh memiliki kolom turunan. Semua elemen dalam array harus bukanNULL
, dan semua nilai dalam kolom harus memiliki dimensi array yang sama.STORED_COLUMN_NAME
: nama kolom tingkat teratas dalam tabel yang akan disimpan dalam indeks vektor. Jenis kolom tidak bolehRANGE
. Kolom tersimpan tidak digunakan jika tabel memiliki kebijakan akses tingkat baris atau kolom memiliki tag kebijakan. Untuk informasi tentang cara mengaktifkan kolom tersimpan, lihat Menyimpan kolom dan pra-filter.DISTANCE_TYPE
: argumen opsional yang menentukan jenis jarak default yang akan digunakan saat melakukan penelusuran vektor menggunakan indeks ini. Nilai yang didukung adalahEUCLIDEAN
,COSINE
, danDOT_PRODUCT
.EUCLIDEAN
adalah defaultnya.Pembuatan indeks itu sendiri selalu menggunakan jarak
EUCLIDEAN
untuk pelatihan, tetapi jarak yang digunakan dalam fungsiVECTOR_SEARCH
dapat berbeda.Jika Anda menentukan nilai untuk argumen
distance_type
dari fungsiVECTOR_SEARCH
, nilai tersebut akan digunakan, bukan nilaiDISTANCE_TYPE
.LEAF_NODE_EMBEDDING_COUNT
: nilaiINT64
yang lebih besar dari atau sama dengan 500 yang menentukan perkiraan jumlah vektor di setiap node daun dari hierarki yang dibuat algoritma TreeAH. Algoritma TreeAH membagi seluruh ruang data menjadi sejumlah daftar, dengan setiap daftar berisi sekitarLEAF_NODE_EMBEDDING_COUNT
titik data. Nilai yang lebih rendah akan membuat lebih banyak daftar dengan lebih sedikit titik data, sedangkan nilai yang lebih besar akan membuat lebih sedikit daftar dengan lebih banyak titik data. Nilai default-nya adalah 1.000, yang sesuai untuk sebagian besar set data.NORMALIZATION_TYPE
: nilaiSTRING
. Nilai yang didukung adalahNONE
atauL2
. Defaultnya adalahNONE
. Normalisasi terjadi sebelum pemrosesan apa pun, baik untuk data tabel dasar maupun data kueri, tetapi tidak mengubah kolom penyematanCOLUMN_NAME
diTABLE_NAME
. Bergantung pada set data, model penyematan, dan jenis jarak yang digunakan selamaVECTOR_SEARCH
, menormalisasi penyematan dapat meningkatkan recall.
Contoh berikut membuat indeks vektor pada kolom embedding
dari my_table
, dan menentukan jenis jarak yang akan digunakan serta opsi TreeAH:
CREATE TABLE my_dataset.my_table(id INT64, embedding ARRAY<FLOAT64>); CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) OPTIONS (index_type = 'TREE_AH', distance_type = 'EUCLIDEAN', tree_ah_options = '{"normalization_type": "L2"}');
Menyimpan kolom dan pra-filter
Untuk lebih meningkatkan efisiensi indeks vektor, Anda dapat menentukan kolom
dari tabel dasar untuk disimpan dalam indeks vektor. Menggunakan kolom tersimpan dapat
mengoptimalkan kueri yang memanggil fungsi VECTOR_SEARCH
dengan cara berikut:
Daripada menelusuri seluruh tabel, Anda dapat memanggil fungsi
VECTOR_SEARCH
pada pernyataan kueri yang memfilter sebelumnya tabel dasar dengan klausaWHERE
. Jika tabel Anda memiliki indeks dan Anda hanya memfilter kolom yang disimpan, BigQuery akan mengoptimalkan kueri dengan memfilter data sebelum melakukan penelusuran, lalu menggunakan indeks untuk menelusuri set hasil yang lebih kecil. Jika Anda memfilter kolom yang tidak disimpan, BigQuery akan menerapkan filter setelah tabel ditelusuri, atau pasca-filter.Fungsi
VECTOR_SEARCH
menghasilkan struct yang disebutbase
yang berisi semua kolom dari tabel dasar. Tanpa kolom yang disimpan, join yang berpotensi mahal diperlukan untuk mengambil kolom yang disimpan dibase
. Jika Anda menggunakan indeks IVF dan kueri hanya memilih kolom yang disimpan daribase
, BigQuery akan mengoptimalkan kueri untuk menghilangkan join tersebut. Untuk indeks TreeAH, join dengan tabel dasar tidak dihapus. Kolom yang disimpan dalam indeks TreeAH hanya digunakan untuk tujuan pra-pemfilteran.
Untuk menyimpan kolom, cantumkan dalam klausa STORING
dari
pernyataan DDL CREATE VECTOR INDEX
.
Menyimpan kolom akan meningkatkan ukuran indeks vektor, jadi sebaiknya simpan
hanya kolom yang paling sering digunakan atau difilter.
Contoh berikut membuat indeks vektor dengan kolom yang disimpan, lalu menjalankan kueri penelusuran vektor yang hanya memilih kolom yang disimpan:
-- Create a table that contains an embedding. CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>, type STRING, creation_time DATETIME, id INT64); -- Create a query table that contains an embedding. CREATE TABLE my_dataset.my_testdata(embedding ARRAY<FLOAT64>, test_id INT64); -- Create a vector index with stored columns. CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) STORING (type, creation_time) OPTIONS (index_type = 'IVF'); -- Select only stored columns from a vector search to avoid an expensive join. SELECT query, base.type, distance FROM VECTOR_SEARCH( TABLE my_dataset.my_table, 'embedding' TABLE my_dataset.my_testdata);
Pra-filter dan pasca-filter
Dalam operasi VECTOR_SEARCH
BigQuery, prapemfilteran dan
pascapemfilteran berfungsi untuk menyaring hasil penelusuran, dengan menerapkan kondisi berdasarkan
kolom metadata yang terkait dengan penyematan vektor. Penting untuk memahami perbedaan, penerapan, dan dampaknya guna mengoptimalkan performa, biaya, dan akurasi kueri.
Pra-pemfilteran dan pasca-pemfilteran ditentukan sebagai berikut:
- Pra-pemfilteran: Menerapkan kondisi filter sebelum penelusuran perkiraan tetangga terdekat (ANN) melakukan penghitungan jarak pada vektor kandidat. Hal ini mempersempit kumpulan vektor yang dipertimbangkan selama penelusuran. Akibatnya, pra-pemfilteran sering kali menghasilkan waktu kueri yang lebih cepat dan mengurangi biaya komputasi, karena penelusuran ANN mengevaluasi lebih sedikit kandidat potensial.
- Pasca-pemfilteran: Menerapkan kondisi filter setelah tetangga terdekat
top_k
awal diidentifikasi oleh penelusuran ANN. Tindakan ini akan meningkatkan kualitas kumpulan hasil akhir berdasarkan kriteria yang ditentukan.
Penempatan klausa WHERE
menentukan apakah filter berfungsi sebagai prefilter atau postfilter.
Untuk membuat pra-filter, klausa WHERE
kueri harus berlaku untuk
argumen tabel dasar fungsi VECTOR_SEARCH
.
Predikat harus berlaku untuk kolom yang disimpan. Jika tidak, predikat akan menjadi
post-filter secara efektif.
Contoh berikut menunjukkan cara membuat pra-filter:
-- Pre-filter on a stored column. The index speeds up the query. SELECT * FROM VECTOR_SEARCH( (SELECT * FROM my_dataset.my_table WHERE type = 'animal'), 'embedding', TABLE my_dataset.my_testdata); -- Filter on a column that isn't stored. The index is used to search the -- entire table, and then the results are post-filtered. You might see fewer -- than 5 matches returned for some embeddings. SELECT query.test_id, base.type, distance FROM VECTOR_SEARCH( (SELECT * FROM my_dataset.my_table WHERE id = 123), 'embedding', TABLE my_dataset.my_testdata, top_k => 5); -- Use pre-filters with brute force. The data is filtered and then searched -- with brute force for exact results. SELECT query.test_id, base.type, distance FROM VECTOR_SEARCH( (SELECT * FROM my_dataset.my_table WHERE id = 123), 'embedding', TABLE my_dataset.my_testdata, options => '{"use_brute_force":true}');
Untuk membuat post-filter, klausa WHERE
kueri harus diterapkan di luar
fungsi VECTOR_SEARCH
, sehingga memfilter hasil yang ditampilkan oleh
penelusuran.
Contoh berikut menunjukkan cara membuat post-filter:
-- Use post-filters. The index is used, but the entire table is searched and -- the post-filtering might reduce the number of results. SELECT query.test_id, base.type, distance FROM VECTOR_SEARCH( TABLE my_dataset.my_table, 'embedding', TABLE my_dataset.my_testdata, top_k => 5) WHERE base.type = 'animal'; SELECT base.id, distance FROM VECTOR_SEARCH( TABLE mydataset.base_table, 'embedding', (SELECT embedding FROM mydataset.query_table), top_k => 10 ) WHERE type = 'document' AND year > 2022
Saat Anda menggunakan pemfilteran pasca, atau saat filter tabel dasar yang Anda tentukan
mereferensikan kolom yang tidak disimpan sehingga bertindak sebagai filter pasca, kumpulan hasil
akhir mungkin berisi kurang dari top_k
baris, bahkan mungkin nol baris,
jika predikat bersifat selektif. Jika Anda memerlukan jumlah hasil tertentu
setelah pemfilteran, pertimbangkan untuk menentukan nilai top_k
yang lebih besar atau meningkatkan
nilai fraction_lists_to_search
dalam panggilan VECTOR_SEARCH
.
Dalam beberapa kasus, terutama jika prafilter sangat selektif, prapemfilteran
juga dapat mengurangi ukuran kumpulan hasil. Jika hal ini terjadi, coba tingkatkan
nilai fraction_lists_to_search
dalam panggilan VECTOR_SEARCH
.
Batasan
- Anda tidak dapat menggunakan tampilan logis dalam prafilter.
- Jika prafilter Anda berisi subkueri, hal ini dapat mengganggu penggunaan indeks.
- Jika mode, jenis, atau skema kolom diubah di tabel dasar, dan jika kolom tersebut disimpan dalam indeks vektor, mungkin ada penundaan sebelum perubahan tersebut ditampilkan dalam indeks vektor. Hingga pembaruan diterapkan ke indeks, kueri penelusuran vektor menggunakan kolom tersimpan yang diubah dari tabel dasar.
- Jika Anda memilih kolom jenis
STRUCT
dari outputquery
kueriVECTOR_SEARCH
pada tabel yang memiliki indeks dengan kolom yang disimpan, seluruh kueri mungkin akan gagal.
Memahami kapan data diindeks
Indeks vektor dikelola sepenuhnya oleh BigQuery dan dimuat ulang secara otomatis saat tabel yang diindeks berubah.
Pengindeksan bersifat asinkron. Ada penundaan antara menambahkan baris baru ke
tabel dasar dan baris baru yang ditampilkan dalam indeks. Namun, fungsi VECTOR_SEARCH
masih mempertimbangkan semua baris dan tidak melewatkan baris yang tidak diindeks. Fungsi ini menelusuri menggunakan indeks untuk data yang diindeks, dan menggunakan penelusuran brute force untuk data yang belum diindeks.
Jika Anda membuat indeks vektor pada tabel yang berukuran lebih kecil dari 10 MB, indeks vektor tidak akan terisi. Demikian pula, jika Anda menghapus data dari tabel yang diindeks dan ukuran tabel di bawah 10 MB, indeks vektor akan dinonaktifkan untuk sementara. Dalam hal ini, kueri penelusuran vektor tidak menggunakan indeks dan
kode indexUnusedReasons
di
bagian vectorSearchStatistics
dari resource Job
adalah BASE_TABLE_TOO_SMALL
. Tanpa indeks,
VECTOR_SEARCH
akan otomatis kembali menggunakan brute force untuk menemukan
tetangga terdekat penyematan.
Jika Anda menghapus kolom yang diindeks dalam tabel, atau mengganti nama tabel itu sendiri, indeks vektor akan otomatis dihapus.
Memantau status indeks vektor
Anda dapat memantau kondisi indeks vektor dengan membuat kueri
tampilan INFORMATION_SCHEMA
. Tampilan berikut berisi metadata pada indeks
vektor:
Tampilan
INFORMATION_SCHEMA.VECTOR_INDEXES
memiliki informasi tentang indeks vektor dalam set data.Setelah pernyataan
CREATE VECTOR INDEX
selesai, indeks masih harus diisi sebelum Anda dapat menggunakannya. Anda dapat menggunakan kolomlast_refresh_time
dancoverage_percentage
untuk memverifikasi kesiapan indeks vektor. Jika indeks vektor belum siap, Anda tetap dapat menggunakan fungsiVECTOR_SEARCH
pada tabel, tetapi mungkin berjalan lebih lambat tanpa indeks.Tampilan
INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS
memiliki informasi tentang kolom yang diindeks vektor untuk semua tabel dalam set data.Tampilan
INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS
memiliki informasi tentang opsi yang digunakan oleh indeks vektor dalam set data.
Contoh indeks vektor
Contoh berikut menunjukkan semua indeks vektor aktif pada tabel dalam set data
my_dataset
, yang terletak di project my_project
. Contoh ini mencakup nama indeks, pernyataan DDL yang digunakan untuk membuatnya, dan persentase cakupannya. Jika
tabel dasar yang diindeks kurang dari 10 MB, indeksnya tidak terisi, dan dalam
hal ini nilai coverage_percentage
adalah 0.
SELECT table_name, index_name, ddl, coverage_percentage FROM my_project.my_dataset.INFORMATION_SCHEMA.VECTOR_INDEXES WHERE index_status = 'ACTIVE';
Hasilnya mirip dengan berikut ini:
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table_name | index_name | ddl | coverage_percentage | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table1 | indexa | CREATE VECTOR INDEX `indexa` ON `my_project.my_dataset.table1`(embeddings) | 100 | | | | OPTIONS (distance_type = 'EUCLIDEAN', index_type = 'IVF', ivf_options = '{"num_lists": 100}') | | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table2 | indexb | CREATE VECTOR INDEX `indexb` ON `my_project.my_dataset.table2`(vectors) | 42 | | | | OPTIONS (distance_type = 'COSINE', index_type = 'IVF', ivf_options = '{"num_lists": 500}') | | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table3 | indexc | CREATE VECTOR INDEX `indexc` ON `my_project.my_dataset.table3`(vectors) | 98 | | | | OPTIONS (distance_type = 'DOT_PRODUCT', index_type = 'TREE_AH', | | | | | tree_ah_options = '{"leaf_node_embedding_count": 1000, "normalization_type": "NONE"}') | | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
Contoh kolom indeks vektor
Kueri berikut mengekstrak informasi tentang kolom yang memiliki indeks vektor:
SELECT table_name, index_name, index_column_name, index_field_path FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS;
Hasilnya mirip dengan berikut ini:
+------------+------------+-------------------+------------------+ | table_name | index_name | index_column_name | index_field_path | +------------+------------+-------------------+------------------+ | table1 | indexa | embeddings | embeddings | | table2 | indexb | vectors | vectors | | table3 | indexc | vectors | vectors | +------------+------------+-------------------+------------------+
Contoh opsi indeks vektor
Kueri berikut mengekstrak informasi tentang opsi indeks vektor:
SELECT table_name, index_name, option_name, option_type, option_value FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS;
Hasilnya mirip dengan berikut ini:
+------------+------------+------------------+------------------+-------------------------------------------------------------------+ | table_name | index_name | option_name | option_type | option_value | +------------+------------+------------------+------------------+-------------------------------------------------------------------+ | table1 | indexa | index_type | STRING | IVF | | table1 | indexa | distance_type | STRING | EUCLIDEAN | | table1 | indexa | ivf_options | STRING | {"num_lists": 100} | | table2 | indexb | index_type | STRING | IVF | | table2 | indexb | distance_type | STRING | COSINE | | table2 | indexb | ivf_options | STRING | {"num_lists": 500} | | table3 | indexc | index_type | STRING | TREE_AH | | table3 | indexc | distance_type | STRING | DOT_PRODUCT | | table3 | indexc | tree_ah_options | STRING | {"leaf_node_embedding_count": 1000, "normalization_type": "NONE"} | +------------+------------+------------------+------------------+-------------------------------------------------------------------+
Memverifikasi penggunaan indeks vektor
Informasi tentang penggunaan indeks vektor tersedia di metadata tugas dari tugas yang menjalankan kueri penelusuran vektor. Anda dapat melihat metadata tugas menggunakan konsol Google Cloud , alat command line bq, BigQuery API, atau library klien.
Saat menggunakan konsol Google Cloud , Anda dapat menemukan informasi penggunaan indeks vektor di kolom Mode Penggunaan Indeks Vektor dan Alasan Indeks Vektor Tidak Digunakan.
Saat menggunakan alat bq atau BigQuery API, Anda dapat menemukan informasi penggunaan indeks vektor di bagian VectorSearchStatistics
dari resource Job
.
Mode penggunaan indeks menunjukkan apakah indeks vektor digunakan dengan memberikan salah satu nilai berikut:
UNUSED
: Tidak ada indeks vektor yang digunakan.PARTIALLY_USED
: Beberapa fungsiVECTOR_SEARCH
dalam kueri menggunakan indeks vektor dan beberapa tidak.FULLY_USED
: Setiap fungsiVECTOR_SEARCH
dalam kueri menggunakan indeks vektor.
Jika nilai mode penggunaan indeks adalah UNUSED
atau PARTIALLY_USED
,
alasan indeks tidak digunakan menunjukkan alasan indeks vektor tidak digunakan dalam kueri.
Misalnya, hasil berikut yang ditampilkan oleh
bq show --format=prettyjson -j my_job_id
menunjukkan bahwa indeks tidak digunakan
karena opsi use_brute_force
ditentukan dalam fungsi
VECTOR_SEARCH
:
"vectorSearchStatistics": { "indexUnusedReasons": [ { "baseTable": { "datasetId": "my_dataset", "projectId": "my_project", "tableId": "my_table" }, "code": "INDEX_SUPPRESSED_BY_FUNCTION_OPTION", "message": "No vector index was used for the base table `my_project:my_dataset.my_table` because use_brute_force option has been specified." } ], "indexUsageMode": "UNUSED" }
Opsi pengelolaan indeks
Untuk membuat indeks dan meminta BigQuery mengelolanya, Anda memiliki dua opsi:
- Menggunakan gabungan slot bersama default: Jika data yang ingin diindeks di bawah batas per organisasi, Anda dapat menggunakan gabungan slot bersama untuk pengelolaan indeks.
- Menggunakan pemesanan Anda sendiri: Untuk mencapai progres pengindeksan yang lebih dapat diprediksi dan konsisten pada workload produksi yang lebih besar, Anda dapat menggunakan pemesanan sendiri untuk pengelolaan indeks.
Menggunakan slot bersama
Jika Anda belum mengonfigurasi project agar menggunakan pemesanan khusus untuk pengindeksan, pengelolaan indeks akan ditangani dalam gabungan slot bersama yang gratis dan tunduk pada batasan berikut.
Jika Anda menambahkan data ke tabel yang menyebabkan ukuran total tabel
yang diindeks melebihi batas organisasi Anda,
BigQuery akan menjeda pengelolaan indeks
untuk semua tabel yang diindeks. Jika hal ini terjadi, kolom index_status
di
tampilan INFORMATION_SCHEMA.VECTOR_INDEXES
akan menampilkan PENDING DISABLEMENT
dan indeks akan dimasukkan dalam antrean untuk dihapus. Selagi
menunggu penonaktifan, indeks
masih digunakan dalam kueri dan Anda akan dikenai biaya untuk penyimpanan indeks.
Setelah indeks dihapus, kolom index_status
akan menampilkan
indeks sebagai TEMPORARILY DISABLED
. Dalam status ini, kueri tidak menggunakan indeks,
dan Anda tidak dikenai biaya untuk penyimpanan indeks. Dalam hal ini,
kode IndexUnusedReason
adalah BASE_TABLE_TOO_LARGE
.
Jika Anda menghapus data dari tabel dan ukuran total tabel yang diindeks
di bawah batas per organisasi, pengelolaan indeks akan dilanjutkan untuk
semua tabel yang diindeks. Kolom index_status
di
tampilan INFORMATION_SCHEMA.VECTOR_INDEXES
adalah ACTIVE
, kueri dapat menggunakan indeks, dan Anda akan dikenai biaya untuk
penyimpanan indeks.
BigQuery tidak menjamin ketersediaan kapasitas dari gabungan slot bersama atau throughput pengindeksan yang Anda lihat. Untuk aplikasi produksi, Anda dapat menggunakan slot khusus untuk pemrosesan indeks.
Menggunakan pemesanan Anda sendiri
Alih-alih menggunakan gabungan slot bersama default, Anda dapat menetapkan pemesanan sendiri untuk mengindeks tabel. Menggunakan reservasi Anda sendiri memastikan performa tugas pengelolaan indeks yang dapat diprediksi dan konsisten, seperti pembuatan, pemuatan ulang, dan pengoptimalan latar belakang.
- Tidak ada batas ukuran tabel saat tugas pengindeksan berjalan di pemesanan Anda.
- Menggunakan pemesanan Anda sendiri memberi Anda fleksibilitas dalam pengelolaan indeks. Jika perlu membuat indeks yang sangat besar atau membuat update besar pada tabel yang diindeks, Anda dapat menambahkan lebih banyak slot ke penetapan untuk sementara.
Untuk mengindeks tabel dalam project dengan pemesanan yang ditentukan,
buat pemesanan
di region tempat tabel Anda berada. Kemudian, tetapkan project ke
pemesanan dengan job_type
ditetapkan ke BACKGROUND
:
SQL
Gunakan
pernyataan DDL CREATE ASSIGNMENT
.
Di Google Cloud konsol, buka halaman BigQuery.
Di editor kueri, masukkan pernyataan berikut:
CREATE ASSIGNMENT `ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID` OPTIONS ( assignee = 'projects/PROJECT_ID', job_type = 'BACKGROUND');
Ganti kode berikut:
ADMIN_PROJECT_ID
: project ID dari project administrasi yang memiliki resource pemesananLOCATION
: lokasi pemesananRESERVATION_NAME
: nama pemesananASSIGNMENT_ID
: ID tugasID harus unik untuk project dan lokasi, diawali dan diakhiri dengan huruf kecil atau angka, dan hanya berisi huruf kecil, angka, dan tanda hubung.
PROJECT_ID
: ID project yang berisi tabel yang akan diindeks. Project ini ditetapkan ke pemesanan.
Klik
Run.
Untuk informasi selengkapnya tentang cara menjalankan kueri, lihat Menjalankan kueri interaktif.
bq
Gunakan perintah bq mk
:
bq mk \ --project_id=ADMIN_PROJECT_ID \ --location=LOCATION \ --reservation_assignment \ --reservation_id=RESERVATION_NAME \ --assignee_id=PROJECT_ID \ --job_type=BACKGROUND \ --assignee_type=PROJECT
Ganti kode berikut:
ADMIN_PROJECT_ID
: project ID dari project administrasi yang memiliki resource pemesananLOCATION
: lokasi pemesananRESERVATION_NAME
: nama pemesananPROJECT_ID
: ID project yang akan ditetapkan ke pemesanan ini
Melihat tugas pengindeksan
Tugas pengindeksan baru dibuat setiap kali indeks dibuat atau diperbarui pada
satu tabel. Untuk melihat informasi tentang tugas, buat kueri
tampilan INFORMATION_SCHEMA.JOBS*
. Anda
dapat memfilter tugas pengindeksan dengan
menetapkan job_type IS NULL AND SEARCH(job_id, '`search_index`')
dalam klausa WHERE
kueri Anda. Contoh berikut mencantumkan lima tugas pengindeksan terbaru
dalam project my_project
:
SELECT * FROM region-us.INFORMATION_SCHEMA.JOBS WHERE project_id = 'my_project' AND job_type IS NULL AND SEARCH(job_id, '`search_index`') ORDER BY creation_time DESC LIMIT 5;
Memilih ukuran pemesanan Anda
Untuk memilih jumlah slot yang tepat untuk pemesanan, Anda harus mempertimbangkan kapan tugas pengelolaan indeks dijalankan, jumlah slot yang digunakan, dan seperti apa penggunaan Anda dari waktu ke waktu. BigQuery memicu tugas pengelolaan indeks dalam situasi berikut:
- Anda membuat indeks pada tabel.
- Data diubah dalam tabel yang diindeks.
- Skema tabel berubah dan hal ini memengaruhi kolom mana yang akan diindeks.
- Data dan metadata indeks dioptimalkan atau diperbarui secara berkala.
Jumlah slot yang Anda perlukan untuk tugas pengelolaan indeks pada tabel bergantung pada faktor-faktor berikut:
- Ukuran tabel
- Laju penyerapan data ke tabel
- Tingkat pernyataan DML yang diterapkan pada tabel
- Penundaan yang dapat diterima untuk membangun dan mempertahankan indeks
- Kompleksitas indeks, biasanya ditentukan oleh atribut data, seperti jumlah istilah duplikat
Memantau Penggunaan dan Progres
Cara terbaik untuk menilai jumlah slot yang Anda perlukan untuk menjalankan
tugas pengelolaan indeks secara efisien adalah dengan memantau penggunaan slot dan menyesuaikan
ukuran pemesanan sebagaimana mestinya. Kueri berikut menghasilkan penggunaan slot harian
untuk tugas pengelolaan indeks. Hanya 30 hari terakhir yang disertakan dalam
region us-west1
:
SELECT TIMESTAMP_TRUNC(job.creation_time, DAY) AS usage_date, -- Aggregate total_slots_ms used for index-management jobs in a day and divide -- by the number of milliseconds in a day. This value is most accurate for -- days with consistent slot usage. SAFE_DIVIDE(SUM(job.total_slot_ms), (1000 * 60 * 60 * 24)) AS average_daily_slot_usage FROM `region-us-west1`.INFORMATION_SCHEMA.JOBS job WHERE project_id = 'my_project' AND job_type IS NULL AND SEARCH(job_id, '`search_index`') GROUP BY usage_date ORDER BY usage_date DESC limit 30;
Jika slot tidak cukup untuk menjalankan tugas pengelolaan indeks, indeks mungkin menjadi tidak sinkron dengan tabelnya dan tugas pengindeksan mungkin gagal. Dalam hal ini, BigQuery membangun ulang indeks dari awal. Untuk menghindari indeks yang tidak sinkron, pastikan Anda memiliki slot yang cukup untuk mendukung pembaruan indeks dari penyerapan dan pengoptimalan data. Untuk informasi selengkapnya tentang pemantauan penggunaan slot, lihat diagram resource admin.
Menghapus indeks vektor
Jika tidak lagi memerlukan indeks vektor atau ingin mengubah kolom mana yang akan
diindeks pada tabel, Anda dapat menghapus indeks di tabel tersebut menggunakan
pernyataan DDL DROP VECTOR INDEX
.
Contoh:
DROP VECTOR INDEX my_index ON my_dataset.indexed_table;
Jika tabel yang diindeks dihapus, indeksnya dihapus secara otomatis.
Langkah berikutnya
- Untuk mengetahui ringkasan kasus penggunaan, harga, dan batasan indeks vektor, lihat Pengantar penelusuran vektor.
- Pelajari cara melakukan penelusuran vektor menggunakan
fungsi
VECTOR_SEARCH
. - Pelajari laporan
CREATE VECTOR INDEX
lebih lanjut. - Coba tutorial Menelusuri embedding dengan penelusuran vektor.