Indeks numerik

Selain mengindeks teks, indeks penelusuran menyediakan cara yang efisien untuk nomor indeks. Ini terutama digunakan untuk menambah kueri penelusuran teks lengkap dengan kondisi pada bidang numerik. Halaman ini menjelaskan cara menambahkan penelusuran numerik indeks ke tabel dan cara membuat token array.

Ringkasan

Spanner mendukung nomor pengindeksan untuk operasi kueri berikut:

  • Equality (comparison_type=>"equality")
  • Inequality (comparison_type=>"all")

Dalam kedua kasus tersebut, bilangan asli (baik bilangan bulat atau floating point) mengalami proses tokenisasi, yang secara konseptual mirip dengan pembuatan teks lengkap. tokenisasi. Ini menghasilkan serangkaian token yang kemudian dapat digunakan kueri untuk menemukan dokumen yang cocok dengan kondisi angka.

Pengindeksan kesetaraan hanya menghasilkan satu token, yang mewakili angka tersebut. Mode ini direkomendasikan jika kueri hanya memiliki kondisi dalam bentuk field = @p dalam klausa WHERE.

Ketidaksetaraan dan pengindeksan kesetaraan dapat mempercepat berbagai kondisi di klausul WHERE dari kueri. Ini mencakup field < @p, field <= @p, field > @p, field >= @p, field BETWEEN @p1 and @p2, dan field <> @p di selain kondisi kesetaraan. Untuk menerapkan jenis pengindeksan ini, Spanner menghasilkan token dalam indeks penelusuran yang mendasarinya. Spanner dapat menghasilkan banyak token untuk setiap nomor yang diindeks, bergantung pada parameter tuning. Jumlah token bergantung pada parameter yang ditetapkan untuk TOKENIZE_NUMBER, seperti algorithm, min, max, dan granularity. Oleh karena itu, penting untuk mengevaluasi parameter tuning dengan hati-hati untuk memastikan keseimbangan yang sesuai antara penyimpanan {i>disk<i} dan waktu pencarian.

Algoritma untuk rentang nomor indeks

Argumen TOKENIZE_NUMBER algorithm memiliki tiga opsi ke rentang nomor indeks: logtree, prefixtree, dan floatingpoint. Masing-masing lebih baik dalam mengindeks distribusi data dan rentang kueri tertentu:

  • logtree paling baik untuk mengindeks data yang didistribusikan secara seragam. Ini adalah setelan default algoritme.
  • prefixtree berfungsi paling baik saat mengindeks data yang didistribusikan secara eksponensial dan saat predikat kueri dalam bentuk "@param > number" atau "@param >= number" (rentang tanpa batas atas). Dibandingkan dengan logtree, algoritma ini menghasilkan lebih sedikit token index untuk angka kecil. Sebagai kueri yang mana klausa WHERE berisi predikat sebelumnya dijelaskan, prefixtree menghasilkan lebih sedikit token kueri, yang dapat meningkatkan tingkat tinggi.
  • floatingpoint paling tepat untuk mengindeks nilai FLOAT64 tempat data yang sudah diindeks dan kueri seringkali berisi pecahan. Saat membuat token FLOAT64 menggunakan logtree atau prefixtree, TOKENIZE_NUMBER mungkin kehilangan presisi karena jumlah granularity bucket dalam rentang min hingga max mendekati resolusi maksimum angka floating point presisi ganda, kira-kira 2^52 bucket. Hal ini dapat membuat kueri kurang efisien, tetapi tidak menyebabkan perilaku yang tidak sesuai. Kehilangan presisi ini tidak terjadi dengan floatingpoint jika argumen precision ditetapkan cukup tinggi. Namun, algoritma floatingpoint menghasilkan lebih banyak token indeks saat precision ditetapkan ke nilai yang lebih besar.

Parameter base mengontrol lebar setiap bucket hierarki dalam algoritma logtree dan prefixtree. Kedua algoritma menghasilkan token yang mewakili node dalam Pohon base-ary dengan lebar node basedistance_from_leaf. Perbedaan algoritma terletak pada prefixtree yang menghilangkan beberapa node hierarki dan memilih token lebih besar dari yang mempercepat kueri lebih besar dari. Semakin besar basis yang dipilih, semakin sedikit token indeks yang dibuat. Namun, nilai base yang lebih besar meningkatkan jumlah kueri maksimum dan token tambahan yang diperlukan.

Angka yang berada di luar rentang [min, max] semuanya diindeks menjadi dua kelompok: satu untuk semua angka yang kurang dari min, dan satu lagi untuk semua angka yang lebih banyak dari max. Hal ini dapat menyebabkan pengambilan berlebihan yang signifikan (pengambilan terlalu banyak angka) ketika rentang yang diminta oleh kueri juga mencakup angka di luar rentang tersebut. Oleh karena itu, tetapkan min dan max ke nilai sempit yang mencakup semua angka input. Seperti semua konfigurasi tokenisasi, mengubah nilai min dan max memerlukan build ulang indeks numerik, jadi biarkan ruang untuk berkembang jika domain akhir kolom tidak diketahui. Permasalahan pengambilan yang berlebihan bukanlah masalah ketepatan karena semua kecocokan potensial diperiksa dengan nomor yang tidak dikelompokkan di akhir proses pencarian; ini hanya potensi masalah efisiensi.

Argumen granularity mengontrol frekuensi downsampling yang diterapkan ke angka sebelum diindeks dalam algoritma berbasis pohon. Sebelum setiap angka ditokenkan, lalu diurutkan ke dalam bucket dengan lebar sama dengan granularity. Semua angka di bucket granularity yang sama akan mendapatkan token yang sama. Artinya bahwa pengambilan berlebihan mungkin terjadi jika nilai perincian ditetapkan ke apa pun selain 1 untuk bilangan integral. Pengambilan berlebih selalu dapat dilakukan untuk angka FLOAT64. Hal ini juga berarti bahwa jika nilai numerik berubah dalam jumlah kecil, sebagian besar tokennya tidak perlu diindeks ulang. Menggunakan granularity yang lebih tinggi dari 1 juga akan mengurangi jumlah token yang perlu dibuat oleh algoritma, tetapi efeknya kurang signifikan dibandingkan dengan efek peningkatan base. Oleh karena itu, sebaiknya 'detail' ditetapkan ke 1.

Tokenisasi array

Selain nilai skalar, TOKENIZE_NUMBER mendukung tokenisasi himpunan bilangan.

Saat TOKENIZE_NUMBER digunakan dengan kolom ARRAY, Anda harus menentukan comparison_type=>"equality". Kueri rentang tidak didukung dengan himpunan bilangan.

Misalnya, perhatikan skema berikut:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Ratings ARRAY<INT64>,
  Ratings_Tokens TOKENLIST
    AS (TOKENIZE_NUMBER(Ratings, comparison_type=>"equality")) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Grades_Tokens);

Kueri berikut menemukan semua album yang memiliki rating 1 atau 2:

SELECT AlbumId
FROM Albums
WHERE ARRAY_CONTAINS_ANY(Ratings, [1, 2])

Kueri berikut menemukan semua album yang diberi rating 1 dan 5:

SELECT AlbumId
FROM Albums
WHERE ARRAY_CONTAINS_ALL(Ratings, [1, 5])

Langkah selanjutnya