Halaman ini menjelaskan cara menambahkan indeks penelusuran ke tabel. Indeks pencarian diperlukan untuk membuat struktur tabel yang yang diperlukan untuk mengizinkan penelusuran teks lengkap di Spanner.
Indeks penelusuran teks lengkap
Anda dapat membuat indeks penelusuran di kolom mana pun yang ingin dibuat
tersedia untuk penelusuran teks lengkap. Untuk membuat indeks penelusuran, gunakan
CREATE SEARCH INDEX
Pernyataan DDL, atau perbarui pernyataan tersebut menggunakan
Pernyataan DDL ALTER SEARCH INDEX
. Spanner
secara otomatis menyusun dan memelihara indeks pencarian, termasuk menambah dan
memperbarui data dalam indeks penelusuran segera setelah data tersebut berubah dalam database.
Indeks penelusuran dapat dipartisi atau tidak dipartisi, bergantung pada jenisnya kueri yang ingin Anda percepat.
Contoh saat indeks yang dipartisi adalah pilihan terbaik adalah ketika aplikasi mengirimkan kueri ke kotak surat email. Setiap kueri dibatasi ke kueri kotak surat.
Contoh saat kueri yang tidak dipartisi adalah pilihan terbaik adalah ada kueri di semua kategori produk dalam katalog produk.
Selain penelusuran teks lengkap, indeks penelusuran Spanner mendukung berikut ini:
- {i>Substring search<i}, yang merupakan jenis kueri untuk mencari {i>string<i} (substring) di dalam isi teks yang lebih besar.
- Akselerasi untuk kueri yang memiliki ekspresi pencocokan numerik dan persis.
- Menggabungkan kondisi pada subset data yang diindeks ke dalam satu pemindaian indeks.
Sementara indeks pencarian mendukung penggunaan data non-tekstual, seperti angka dan string pencocokan persis, kasus penggunaan yang paling umum untuk indeks penelusuran adalah mengindeks teks dalam dokumen.
Untuk menunjukkan kemampuan indeks pencarian, anggaplah ada sebuah tabel yang menyimpan informasi tentang album musik:
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX)
) PRIMARY KEY(AlbumId);
Spanner memiliki beberapa
fungsi token yang membuat
token kata. Untuk mengubah tabel sebelumnya agar pengguna dapat menjalankan penelusuran teks lengkap untuk menemukan
judul album, gunakan fungsi TOKENIZE_FULLTEXT
untuk membuat token dari
judul album. Lalu, buat kolom yang menggunakan jenis data TOKENLIST
untuk menyimpan output tokenisasi dari TOKENIZE_FULLTEXT
. Untuk contoh ini,
kita membuat kolom AlbumTitle_Tokens
.
ALTER TABLE Albums
ADD COLUMN AlbumTitle_Tokens TOKENLIST
AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN;
Berikut ini menggunakan DDL CREATE SEARCH INDEX
untuk membuat indeks penelusuran
(AlbumsIndex
) pada token AlbumTitle
(AlbumTitle_Tokens
):
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens);
Setelah menambahkan indeks penelusuran, gunakan kueri SQL untuk menemukan album yang cocok kriteria pencarian. Contoh:
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
Konsistensi data
Saat indeks dibuat, Spanner menggunakan proses otomatis untuk mengisi ulang data untuk memastikan konsistensi. Saat operasi tulis di-commit, indeks diperbarui dalam transaksi yang sama. Spanner secara otomatis melakukan pemeriksaan konsistensi data.
Definisi skema indeks penelusuran
Indeks penelusuran ditentukan pada satu atau beberapa kolom TOKENLIST
pada tabel. Telusuri
indeks memiliki komponen berikut:
- Tabel dasar: Tabel Spanner yang memerlukan pengindeksan.
- Kolom
TOKENLIST
: Kumpulan kolom yang menentukan token yang memerlukan pengindeksan. Urutan kolom ini tidak penting.
Misalnya, dalam pernyataan berikut, tabel dasarnya adalah Album. TOKENLIST
kolom dibuat di AlbumTitle
(AlbumTitle_Tokens
) dan Rating
(Rating_Tokens
).
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
SingerId INT64 NOT NULL,
ReleaseTimestamp INT64 NOT NULL,
AlbumTitle STRING(MAX),
Rating FLOAT64,
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN
) PRIMARY KEY(AlbumId);
Gunakan pernyataan CREATE SEARCH INDEX
berikut untuk membuat indeks penelusuran menggunakan token untuk AlbumTitle
dan Rating
:
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens, Rating_Tokens)
PARTITION BY SingerId
ORDER BY ReleaseTimestamp DESC
Indeks penelusuran memiliki opsi berikut:
- Partisi: Grup kolom opsional yang membagi indeks penelusuran. Membuat kueri indeks yang dipartisi sering kali jauh lebih efisien dibandingkan membuat kueri indeks yang tidak dipartisi. Untuk informasi selengkapnya, lihat Indeks penelusuran partisi.
- Kolom tata urutan: Kolom
INT64
opsional yang menetapkan urutan pengambilan dari indeks penelusuran. Untuk selengkapnya informasi, lihat Telusuri tata urutan indeks. - Interleaving: Seperti indeks sekunder, Anda dapat menyisipkan indeks penelusuran. Indeks penelusuran berselisih menggunakan lebih sedikit resource untuk menulis dan menggabungkan pada tabel dasar. Untuk informasi selengkapnya, lihat Penelusuran sisipan indeks.
- Klausa opsi: Daftar pasangan nilai kunci yang menggantikan nilai default pengaturan indeks pencarian.
Untuk informasi selengkapnya, lihat referensi CREATE SEARCH INDEX
.
Tata letak internal indeks penelusuran
Elemen penting dari representasi internal indeks pencarian adalah
docid, yang berfungsi sebagai representasi kunci utama yang hemat penyimpanan
dari tabel dasar yang bisa panjangnya sembarangan. Hal itu juga yang menciptakan
urutan tata letak data internal sesuai dengan ORDER BY
yang diberikan pengguna
kolom
Klausa CREATE SEARCH INDEX
. ASCII direpresentasikan
sebagai satu atau
dua bilangan bulat 64-bit.
Indeks penelusuran diimplementasikan secara internal sebagai pemetaan dua tingkat:
- Token ke docid
- Docid ke kunci utama tabel dasar
Skema ini menghasilkan penghematan penyimpanan yang signifikan dengan Spanner
tidak perlu menyimpan kunci utama
tabel basis lengkap untuk setiap
<token, document>
pasangan.
Ada dua jenis indeks fisik yang mengimplementasikan dua level pemetaan:
- Indeks sekunder yang memetakan kunci partisi dan asam ke tabel dasar
{i>primary key<i}-nya. Pada contoh di bagian sebelumnya, hal ini memetakan
{SingerId, ReleaseTimestamp, uid}
ke{SingerId, AlbumId}
. Indeks sekunder juga menyimpan semua kolom yang ditentukan dalam klausaSTORING
dariCREATE SEARCH INDEX
. - Indeks token memetakan token ke docid, serupa dengan indeks terbalik pada
literatur untuk pengambilan informasi. Spanner mempertahankan
indeks token terpisah untuk setiap
TOKENLIST
dari indeks penelusuran. Secara logis, Indeks token mengelola daftar docid untuk setiap token dalam setiap partisi (dikenal dalam pengambilan informasi sebagai daftar postingan). Daftar ini diurutkan oleh token untuk pengambilan cepat, dan di dalam daftar {i> docid<i} digunakan untuk memesan. Indeks token individual adalah detail implementasi yang tidak diekspos Spanner API.
Spanner mendukung empat opsi berikut untuk docid.
Indeks penelusuran | Docid | Perilaku |
---|---|---|
Klausa ORDER BY dihapus untuk indeks penelusuran |
{ uid } |
Spanner menambahkan nilai unik (UID) tersembunyi untuk mengidentifikasi setiap baris. |
ORDER BY column |
{ column, uid } |
Spanner menambahkan kolom UID sebagai binding di antara baris dengan nilai column yang sama dalam partisi. |
ORDER BY column ... OPTIONS (disable_automatic_uid_column=true) |
{ column } |
Kolom UID tidak ditambahkan. Nilai column harus unik dalam partisi. |
ORDER BY column1, column2 ... OPTIONS (disable_automatic_uid_column=true) |
{ column1, column2 } |
Kolom UID tidak ditambahkan. Kombinasi nilai column1 dan column2 harus unik dalam partisi. |
Catatan penggunaan:
- Kolom UID internal tidak diekspos melalui Spanner Compute Engine API.
- Dalam indeks yang tidak menambahkan UID, transaksi apa pun akan gagal jika menghasilkan dua baris dengan jumlah yang sama (partisi,tata urutan).
Misalnya, perhatikan data berikut:
AlbumId | SingerId | ReleaseTimestamp | AlbumTitle |
---|---|---|---|
a1 | 1 | 997 | besar |
a2 | 1 | 743 | Kucing besar |
Dengan asumsi kolom presort berada dalam urutan menaik, isi token
dipartisi oleh SingerId
akan mempartisi konten indeks token dalam
dengan cara berikut:
SingerId | _token | ReleaseTimestamp | uid |
---|---|---|---|
1 | besar | 743 | uid1 |
1 | besar | 997 | uid2 |
1 | cat | 743 | uid1 |
1 | dog | 997 | uid2 |
Sharding indeks penelusuran
Saat Spanner membagi tabel. mendistribusikan data indeks pencarian sehingga semua token dalam baris tabel dasar tertentu berada di bagian yang sama. Dengan kata lain, indeks penelusuran merupakan hasil sharding dokumen. Strategi sharding ini memiliki implikasi performa yang signifikan:
- Jumlah server yang berkomunikasi dengan setiap transaksi tetap
konstan, terlepas dari jumlah token atau jumlah
TOKENLIST
kolom. - Kueri penelusuran yang melibatkan beberapa ekspresi bersyarat dijalankan secara independen pada setiap bagian, sehingga menghindari overhead performa yang terkait dengan gabungan terdistribusi.
Indeks penelusuran memiliki dua mode distribusi:
- Sharding seragam (default). Dalam sharding seragam, data terindeks untuk setiap baris tabel dasar ditetapkan secara acak ke bagian indeks dari partisi.
- Sharding urutan penyortiran. Dalam sharding tata urutan, data untuk setiap baris tabel dasar
ditetapkan ke bagian indeks partisi berdasarkan
ORDER BY
seperti baris dan kolom. Misalnya, dalam kasus tata urutan menurun, semua baris dengan nilai urutan tertinggi muncul di bagian indeks pertama partisi, dan grup nilai tata urutan tertinggi berikutnya di pemisahan berikutnya.
Mode sharding ini memiliki imbal balik antara risiko hotspotting dan biaya kueri:
- Indeks penelusuran dengan sharding tata urutan rentan terhadap hotspotting ketika indeks diurutkan berdasarkan stempel waktu. Untuk informasi selengkapnya, lihat Memilih kunci utama untuk mencegah hotspot. Di sisi lain, ketika beban tulis meningkat pada berbagai dokumen, sharding yang seragam memastikan bahwa peningkatan didistribusikan secara merata sharding.
- Pemisahan berbasis beban standar membuat pemisahan tambahan yang menyediakan perlindungan yang memadai terhadap hotspotting. Kelemahan dari sharding seragam bahwa ia dapat menggunakan lebih banyak sumber daya untuk beberapa jenis kueri.
Mode sharding indeks penelusuran dikonfigurasi menggunakan klausa OPTIONS
:
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens, Rating_Tokens)
PARTITION BY SingerId
ORDER BY ReleaseTimestamp DESC
OPTIONS (sort_order_sharding = true);
Jika sort_order_sharding=false
ditetapkan atau tidak ditentukan, indeks penelusuran akan
yang dibuat menggunakan sharding seragam.
Indeks penelusuran berselisih
Seperti indeks sekunder, Anda dapat menyisipkan indeks penelusuran di tabel induk dari tabel dasar. Alasan utama untuk menggunakan penelusuran sisipan indeks adalah untuk menempatkan data tabel dasar dengan data indeks untuk partisi kecil. Kolokasi oportunistik ini memiliki keuntungan sebagai berikut:
- Penulisan tidak perlu melakukan commit dua fase.
- Sambungan belakang indeks penelusuran dengan tabel dasar tidak didistribusikan.
Indeks penelusuran berselisih memiliki batasan berikut:
- Hanya di-sharding urutan penyortiran indeks dapat disisipi.
- Indeks penelusuran hanya dapat disisipi di tabel tingkat teratas (bukan di turunan tabel).
- Seperti tabel sisipan dan indeks sekunder, buatlah kunci dari
tabel induk sebagai awalan dari kolom
PARTITION BY
di sisipan indeks penelusuran.
Contoh berikut menunjukkan cara menentukan indeks penelusuran sisipan:
CREATE TABLE Singers (
SingerId INT64 NOT NULL
) PRIMARY KEY(SingerId);
CREATE TABLE Albums (
SingerId INT64 NOT NULL,
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(SingerId, AlbumId),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens)
PARTITION BY SingerId
INTERLEAVE IN Singers
OPTIONS (sort_order_sharding = true);
Indeks penelusuran yang difilter dengan NULL
Indeks penelusuran dapat menggunakan sintaksis WHERE column IS NOT NULL
untuk
mengecualikan baris tabel dasar. Pemfilteran NULL bisa berlaku
untuk kunci partisi,
kolom pesanan, dan kolom yang disimpan. Pemfilteran NULL pada kolom array yang disimpan tidak
diizinkan.
Contoh
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens)
STORING Genre
WHERE Genre IS NOT NULL
Kueri harus menentukan kondisi pemfilteran NULL (Genre IS NOT NULL
untuk
contoh ini) dalam klausa WHERE
. Jika tidak, Pengoptimal Kueri tidak dapat
menggunakan indeks pencarian. Untuk informasi selengkapnya, lihat
Persyaratan kueri SQL.
Gunakan pemfilteran NULL pada kolom yang dihasilkan untuk mengecualikan baris berdasarkan kriteria arbitrer. Untuk informasi selengkapnya, lihat Membuat indeks parsial menggunakan kolom yang dibuat.
Langkah selanjutnya
- Pelajari tokenisasi dan tokenizer Spanner.
- Pelajari indeks numerik.
- Pelajari partisi indeks.