App Engine menentukan indeks sederhana di setiap properti entity.
Aplikasi App Engine dapat menentukan indeks kustom lebih lanjut dalam file konfigurasi indeks bernama
index.yaml
. Server pengembangan secara otomatis menambahkan saran ke file ini saat menemukan kueri yang tidak dapat dijalankan dengan indeks yang ada.
Anda dapat menyesuaikan indeks secara manual dengan mengedit file sebelum mengupload aplikasi.
Catatan: Mekanisme kueri berbasis indeks mendukung berbagai kueri dan cocok untuk sebagian besar aplikasi. Namun, mekanisme ini tidak mendukung beberapa jenis kueri yang umum digunakan dalam teknologi database lainnya: khususnya, join dan kueri agregat tidak didukung dalam mesin kueri Datastore. Lihat halaman Kueri Datastore untuk mengetahui batasan kueri Datastore.
Definisi dan struktur indeks
Indeks ditentukan pada daftar properti dari jenis entity tertentu, dengan urutan yang sesuai (menaik atau menurun) untuk setiap properti. Untuk digunakan dengan kueri ancestor, indeks juga dapat menyertakan entity ancestor secara opsional.
Tabel indeks berisi kolom untuk setiap properti yang dinamai dalam definisi indeks. Setiap baris tabel mewakili entity di Datastore yang merupakan kemungkinan hasil untuk kueri berdasarkan indeks. Entity disertakan dalam indeks hanya jika memiliki nilai terindeks yang ditetapkan untuk setiap properti yang digunakan dalam indeks; jika definisi indeks mengacu pada properti yang tidak memiliki nilai dengan entity, entity tersebut tidak akan muncul dalam indeks, dan oleh karena itu tidak akan ditampilkan sebagai hasil untuk kueri apa pun berdasarkan indeks tersebut.
Baris tabel indeks diurutkan terlebih dahulu berdasarkan ancestor, lalu menurut nilai properti, dalam urutan yang ditentukan dalam definisi indeks. Indeks sempurna untuk kueri, yang memungkinkan kueri dijalankan dengan paling efisien, ditentukan pada properti berikut, secara berurutan:
- Properti yang digunakan dalam filter kesetaraan
- Properti yang digunakan dalam filter ketidaksetaraan (maksimal satu)
- Properti yang digunakan dalam tata urutan
Hal ini memastikan bahwa semua hasil untuk setiap kemungkinan eksekusi kueri akan muncul dalam baris tabel yang berurutan. Datastore menjalankan kueri menggunakan indeks sempurna dengan langkah-langkah berikut:
- Mengidentifikasi indeks yang sesuai dengan jenis, properti filter, operator filter, dan tata urutan pada kueri.
- Memindai dari awal indeks hingga entity pertama yang memenuhi semua kondisi filter kueri.
- Terus memindai indeks, menampilkan setiap entity secara bergantian, sampai
- menemukan entity yang tidak memenuhi kondisi filter, atau
- mencapai akhir indeks, atau
- telah mengumpulkan jumlah hasil maksimum yang diminta oleh kueri.
Misalnya, pertimbangkan kueri berikut:
Indeks sempurna untuk kueri ini adalah tabel kunci untuk entity jenis
Person
, dengan kolom untuk nilai
properti LastName
dan
Height
. Indeks diurutkan terlebih dahulu dalam urutan menaik berdasarkan LastName
, lalu dalam urutan menurun berdasarkan Height
.
Untuk membuat indeks ini, konfigurasikan indeks Anda seperti ini:
indexes:
- kind: Person
properties:
- name: LastName
direction: asc
- name: Height
direction: desc
Dua kueri dengan bentuk yang sama tetapi dengan nilai filter yang berbeda menggunakan indeks yang sama. Misalnya, kueri berikut menggunakan indeks yang sama dengan indeks di atas:
Dua kueri berikut juga menggunakan indeks yang sama, meskipun bentuknya berbeda:
dan
Konfigurasi indeks
Secara default, Datastore secara otomatis menetapkan indeks terlebih dahulu untuk setiap properti dari setiap jenis entity. Indeks yang telah ditetapkan ini cukup untuk menjalankan
banyak kueri sederhana, seperti kueri khusus kesetaraan dan kueri ketidaksetaraan
sederhana. Untuk semua kueri lainnya, aplikasi harus menentukan indeks yang diperlukan
dalam file konfigurasi indeks
bernama index.yaml
. Jika aplikasi mencoba menjalankan kueri
yang tidak dapat dijalankan dengan indeks yang tersedia (baik yang telah ditetapkan
maupun yang ditentukan dalam file konfigurasi indeks), kueri akan gagal.
Datastore membuat indeks otomatis untuk kueri dalam bentuk berikut:
- Kueri Kindless hanya menggunakan ancestor dan filter kunci
- Kueri yang hanya menggunakan filter ancestor dan kesetaraan
- Kueri yang hanya menggunakan filter ketidaksetaraan (yang terbatas untuk satu properti)
- Kueri yang hanya menggunakan filter ancestor, filter kesetaraan pada properti, dan filter ketidaksetaraan pada kunci
- Kueri tanpa filter dan hanya satu tata urutan di satu properti, baik menaik ataupun menurun
Bentuk kueri lain mengharuskan indeksnya ditentukan dalam file konfigurasi indeks, termasuk:
- Kueri dengan filter ancestor dan ketidaksetaraan
- Kueri dengan satu atau beberapa filter ketidaksetaraan di sebuah properti dan satu atau beberapa filter kesetaraan di properti lainnya
- Kueri dengan tata urutan pada kunci dalam urutan menurun
- Kueri dengan beberapa tata urutan
Indeks dan properti
Berikut adalah beberapa pertimbangan khusus yang perlu diingat tentang indeks dan kaitannya dengan properti entity di Datastore:
Properti dengan jenis nilai campuran
Jika dua entity memiliki properti dengan nama yang sama tetapi jenis nilai yang berbeda, indeks properti akan terlebih dahulu mengurutkan entity berdasarkan jenis nilai, lalu berdasarkan pengurutan sekunder yang sesuai dengan setiap jenis. Misalnya, jika dua entity masing-masing memiliki properti bernama age
, satu dengan nilai bilangan bulat dan satu dengan nilai string, entity dengan nilai bilangan bulat selalu mendahului entity dengan nilai string ketika diurutkan berdasarkan properti age
, terlepas dari nilai properti itu sendiri.
Hal ini perlu diperhatikan terutama dalam kasus bilangan bulat dan angka floating point,
yang diperlakukan sebagai jenis terpisah oleh Datastore.
Karena semua bilangan bulat diurutkan sebelum semua float, properti dengan nilai bilangan bulat 38
diurutkan sebelum properti dengan nilai floating point 37.5
.
Properti yang tidak terindeks
Jika mengetahui bahwa Anda tidak perlu memfilter atau mengurutkan properti tertentu, Anda dapat memberi tahu Datastore agar tidak mempertahankan entri indeks untuk properti tersebut dengan mendeklarasikan properti tidak terindeks. Tindakan ini dapat menurunkan biaya menjalankan aplikasi Anda dengan mengurangi jumlah penulisan yang harus dilakukan oleh Datastore. Entity dengan properti yang tidak terindeks berperilaku seolah-olah properti tersebut tidak ditetapkan: kueri dengan filter atau tata urutan di properti yang tidak terindeks tidak akan pernah cocok dengan entity tersebut.
Catatan: Jika properti muncul dalam indeks yang terdiri dari beberapa properti, maka menyetelnya ke tidak terindeks akan mencegahnya agar tidak terindeks dalam indeks yang dikombinasikan.
Misalnya, suatu entity memiliki properti a dan b dan
Anda ingin membuat indeks yang dapat memenuhi
kueri seperti WHERE a ="bike" and b="red"
. Selain itu, misalnya Anda tidak mempermasalahkan kueri WHERE a="bike"
dan WHERE b="red"
.
Jika Anda menetapkan a ke tidak terindeks serta membuat indeks untuk a dan b, Datastore tidak akan membuat entri indeks untuk indeks a dan b, sehingga kueri WHERE a="bike" and b="red"
tidak akan berfungsi. Agar Datastore dapat membuat entri untuk indeks a dan
b, a dan b harus diindeks ini.
Anda mendeklarasikan properti yang tidak diindeks dengan menetapkan noindex
di
tag kolom struct:
Namun, perhatikan bahwa mengubah properti dari tidak diindeks menjadi diindeks tidak memengaruhi entity yang sudah ada yang mungkin telah dibuat sebelum perubahan tersebut. Pemfilteran kueri pada properti tidak akan menampilkan entity yang sudah ada tersebut, karena entity tersebut tidak ditulis ke indeks kueri saat dibuat. Agar entity dapat diakses oleh kueri mendatang, Anda harus menulis ulang entity tersebut ke Datastore agar dapat dimasukkan dalam indeks yang sesuai. Artinya, Anda harus melakukan hal berikut untuk setiap entity yang sudah ada:
- Ambil (dapatkan) entity dari Datastore.
- Menulis (put) entity kembali ke Datastore.
Demikian pula, mengubah properti dari diindeks menjadi tidak terindeks hanya memengaruhi entity yang kemudian ditulis ke Datastore. Entri indeks untuk setiap entity yang ada dengan properti tersebut akan tetap ada sampai entity tersebut diperbarui atau dihapus. Untuk menghindari hasil yang tidak diinginkan, Anda harus menghapus permanen kode dari semua kueri yang memfilter atau mengurutkan berdasarkan properti (yang kini tidak terindeks).
Batas indeks
Datastore menetapkan batas jumlah dan ukuran keseluruhan entri indeks yang dapat dikaitkan dengan satu entity. Batas ini cukup besar, dan sebagian besar aplikasi tidak terpengaruh. Namun, ada situasi saat Anda mungkin mencapai batas tersebut.
Sesuai deskripsidi atas ,
Datastore membuat entri dalam indeks yang telah ditentukan untuk setiap
properti setiap entity kecuali
[]byte
yang telah Anda deklarasikan
secara eksplisit sebagaitidak terindeks ini. Properti
juga dapat disertakan dalam indeks kustom tambahan yang dideklarasikan di
file konfigurasi index.yaml
Anda. Asalkan suatu entity tidak memiliki properti daftar, entity akan memiliki maksimal satu entri di setiap indeks kustom tersebut (untuk indeks non-ancestor) atau satu entri untuk setiap ancestor entity (untuk indeks ancestor). Setiap entri indeks ini harus diperbarui|
setiap kali nilai properti berubah.
Untuk properti yang memiliki nilai tunggal untuk setiap entity, setiap kemungkinan nilai hanya perlu disimpan sekali per entity dalam indeks properti yang telah ditentukan. Meski demikian, entity dengan banyak properti bernilai tunggal dapat melebihi batas entri indeks atau batas ukuran. Demikian pula, entity yang dapat memiliki beberapa nilai untuk properti yang sama memerlukan entri indeks terpisah untuk setiap nilai; sekali lagi, jika jumlah kemungkinan nilainya besar, entity tersebut dapat melebihi batas entri.
Situasi ini menjadi lebih buruk jika entity memiliki beberapa properti, yang masing-masing dapat memiliki banyak nilai. Untuk mengakomodasi entity semacam itu, indeks harus menyertakan entri untuk setiap kemungkinan kombinasi nilai properti. Indeks kustom yang merujuk ke beberapa properti, yang masing-masing dengan beberapa nilai, kombinasinya dapat "meledak", sehingga memerlukan banyak entri untuk entity yang hanya memiliki sedikit kemungkinan nilai properti. Indeks yang meledak tersebut dapat secara drastis meningkatkan biaya penulisan entity ke Datastore, karena banyaknya jumlah entri indeks yang harus diperbarui, dan juga dapat dengan mudah menyebabkan entity melebihi batas entri indeks atau batas ukuran.
Mempertimbangkan kueri
yang menyebabkan SDK menyarankan indeks berikut:
Indeks ini akan memerlukan total|X|
*
|Y|
*
|Date|
entri untuk setiap entity (dengan |X|
mengacu pada jumlah nilai yang terkait dengan entity untuk properti X
). Misalnya, kode berikut
membuat entity dengan empat nilai untuk properti x
, tiga nilai untuk properti
y
, dan date
yang ditetapkan ke tanggal saat ini. Ini akan memerlukan 12 entri indeks, satu untuk setiap kemungkinan kombinasi nilai properti:
(1
, "red"
, <now>
)
(1
, "green"
, <now>
)
(1
, "blue"
, <now>
)
(2
, "red"
, <now>
)
(2
, "green"
, <now>
)
(2
, "blue"
, <now>
)
(3
, "red"
, <now>
)
(3
, "green"
, <now>
)
(3
, "blue"
, <now>
)
(4
, "red"
, <now>
)
(4
, "green"
, <now>
)
(4
, "blue"
, <now>
)
Jika properti yang sama diulang beberapa kali, Datastore dapat mendeteksi exploding index dan menyarankan indeks alternatif. Namun, dalam semua kasus lainnya (seperti kueri yang ditentukan dalam contoh ini), Datastore akan menghasilkan exploding index. Dalam kasus ini, Anda dapat menghindari exploding index dengan mengonfigurasi indeks secara manual dalam file konfigurasi indeks:
Tindakan ini mengurangi jumlah entri yang diperlukan menjadi hanya(|X|
*
|Date|
+
|Y|
*
|Date|)
, atau 7 entri, bukan 12:
(1
, <now>
)
(2
, <now>
)
(3
, <now>
)
(4
, <now>
)
("red"
, <now>
)
("green"
, <now>
)
("blue"
, <now>
)
Setiap operasi put yang akan menyebabkan indeks melebihi entri indeks atau batas ukuran
akan gagal dengan
menampilkan error. Teks error
menjelaskan batas yang terlampaui
("Too many indexed properties"
atau "Index entries too large"
) dan
indeks kustom mana yang menyebabkannya. Jika Anda membuat indeks baru yang akan melebihi
batas entity apa pun saat di-build, kueri terhadap indeks akan gagal dan
indeks akan muncul dalam status Error
di Konsol Google Cloud. Untuk
menyelesaikan indeks dalam status Error
:
Hapus indeks di status
Error
dari fileindex.yaml
Anda.Jalankan perintah berikut dari direktori tempat
index.yaml
Anda berada untuk menghapus indeks tersebut dari Datastore:gcloud datastore indexes cleanup index.yaml
Selesaikan penyebab error. Contoh:
- Merumuskan kembali definisi indeks dan kueri yang sesuai.
- Menghapus entity yang menyebabkan exploding index.
Tambahkan kembali indeks ke file
index.yaml
Anda.Jalankan perintah berikut dari direktori tempat
index.yaml
Anda berada untuk membuat indeks di Datastore:gcloud datastore indexes create index.yaml
Anda dapat menghindari exploding index dengan menghindari kueri yang memerlukan indeks kustom menggunakan properti daftar. Seperti yang dijelaskan di atas, ini mencakup kueri dengan beberapa tata urutan atau kueri dengan campuran filter kesetaraan dan ketidaksetaraan.