Topik ini menjelaskan praktik terbaik untuk membuat indeks di ApsaraDB for MongoDB, termasuk menganalisis efisiensi indeks, mengoptimalkan opsi indeks, dan membuat indeks yang efisien untuk kueri tertentu.
Cara memilih indeks
ApsaraDB for MongoDB mendukung berbagai jenis indeks. Pilih tipe indeks berdasarkan skenario Anda.
Gunakan Indeks Kunci Tunggal
Jika hanya melakukan kueri kunci tunggal dalam penggunaan ApsaraDB for MongoDB, buatlah indeks kunci tunggal.
Gunakan Indeks Majemuk
Untuk kueri kunci tunggal dan multi-kunci dalam penggunaan ApsaraDB for MongoDB, buatlah indeks majemuk yang mendukung hingga 32 kunci. Sebagai contoh, jalankan perintah berikut untuk membuat indeks majemuk pada bidang category dan item:
db.products.createIndex( { "category": 1, "item": 1 } )Gunakan Indeks Teks
Indeks konvensional digunakan untuk mencocokkan nilai dari sebuah bidang. Jika ingin mencocokkan kata-kata tertentu dalam bidang teks panjang, gunakan indeks teks. Untuk informasi lebih lanjut tentang indeks teks, lihat Indeks Teks pada Penyebaran Mandiri.
Tentukan aturan pengurutan indeks
Jika menggunakan indeks untuk perbandingan string, tentukan aturan pengurutan yang sama untuk operasi kueri. Jika aturan pengurutan berbeda, indeks tidak akan mendukung perbandingan string dari bidang indeks.
Contoh berikut menunjukkan koleksi dengan indeks pada bidang string myColl. Indeks tersebut menggunakan lokal aturan pengurutan category "fr":
db.myColl.createIndex( { category: 1 }, { collation: { locale: "fr" } } )Tentukan aturan pengurutan yang sama dengan indeks untuk operasi kueri berikut:
db.myColl.find( { category: "cafe" } ).collation( { locale: "fr" } )Operasi kueri berikut menggunakan default "simple" aturan pengurutan biner dan tidak dapat menggunakan indeks:
db.myColl.find( { category: "cafe" } )Untuk indeks majemuk dengan awalan kunci bukan string, array, atau dokumen tertanam, operasi kueri dengan aturan pengurutan berbeda masih dapat menggunakan indeks untuk mendukung perbandingan awalan kunci. Untuk informasi lebih lanjut tentang aturan pengurutan, lihat Lokal Aturan Pengurutan dan Parameter Default.
Analisis indeks berdasarkan log kueri lambat
ApsaraDB for MongoDB mengoptimalkan indeks untuk mengurangi jumlah koleksi yang dipindai. Fokuskan analisis pada metrik DocsExamined dan KeysExamined dalam log kueri lambat. Untuk informasi lebih lanjut tentang cara melihat log kueri lambat, lihat Lihat Log Kueri Lambat.
DocsExamined: jumlah dokumen yang dipindai untuk permintaan kueri. Nilai metrik yang besar menunjukkan bahwa banyak entri non-indeks yang perlu dipindai. Dalam hal ini, kami sarankan Anda membuat indeks untuk bidang dengan banyak dokumen yang dipindai.
KeysExamined: jumlah kunci yang dipindai dalam indeks tertentu. Jika nilai metriknya besar tetapi nilai nreturned yang dikembalikan kecil, banyak kunci indeks yang dipindai untuk mendapatkan data yang memenuhi kondisi kueri tertentu, yang menunjukkan bahwa indeks tidak efisien. Dalam hal ini, Anda harus menyesuaikan indeks atau membuat indeks lain.
Berikut adalah logika analisis indeks:
Pemindaian Koleksi Penuh (kata kunci: COLLSCAN dan DocsExamined)
COLLSCAN menunjukkan pemindaian koleksi penuh. Setelah operasi seperti kueri, pembaruan, atau penghapusan, Anda dapat menemukan kata kunci COLLSCAN saat melihat log permintaan lambat. Buatlah indeks untuk bidang yang sering dikueri.
Bidang DocsExamined menunjukkan jumlah dokumen yang dipindai untuk permintaan kueri. Nilai lebih tinggi menunjukkan penggunaan sumber daya CPU yang lebih besar oleh permintaan ini.
Indeks yang Tidak Sesuai (kata kunci: IXSCAN dan keysExamined)
Bidang keysExamined menunjukkan jumlah kunci indeks yang dipindai untuk permintaan yang menggunakan indeks. Nilai lebih tinggi menunjukkan penggunaan sumber daya CPU yang lebih besar oleh permintaan ini.
Jika indeks tidak sesuai atau cocok dengan sejumlah besar data, indeks tersebut tidak dapat mengurangi beban CPU atau mempercepat eksekusi permintaan.
Jika menemukan kata kunci SORT dalam log kueri lambat, gunakan indeks untuk mengoptimalkan kinerja pengurutan. Untuk informasi lebih lanjut, lihat Aturan ESR (Equality, Sort, Range).
Cara mengoptimalkan indeks
Gunakan covered queries
Kueri tertutup mengembalikan hasil langsung dari indeks tanpa mengakses dokumen sumber. Ini sangat efisien. Untuk menentukan apakah sebuah kueri adalah kueri tertutup, gunakan perintah explain(). Jika keluaran dari explain() menunjukkan bahwa totalDocsExamined adalah 0, kueri tersebut ditutupi oleh indeks.
Jika keluaran dari explain() tidak berisi bidang totalDocsExamined, jalankan kueri dalam mode executionStats atau allPlansExecution. Sebagai contoh, gunakan explain("executionStats") atau explain("allPlansExecution").
Saat menerapkan kueri tertutup, bidang _id selalu dikembalikan secara default. Ini adalah jebakan umum. Secara eksplisit kecualikan _id dari hasil kueri atau tambahkan ke indeks.
Dalam kluster sharded, MongoDB harus mengakses secara internal bidang kunci sharding. Agar kueri tertutup, kunci sharding harus menjadi bagian dari indeks. Oleh karena itu, praktik terbaik adalah menyertakan kunci sharding dalam indeks Anda.
Hapus indeks redundan
Indeks bersifat intensif sumber daya. Indeks dapat mengonsumsi RAM dan sumber daya disk meskipun kompresi digunakan dalam mesin penyimpanan WiredTiger dari ApsaraDB for MongoDB. Saat bidang diperbarui, indeks terkait juga harus dipelihara, menambah beban CPU dan I/O disk. Oleh karena itu, evaluasi dengan hati-hati dan hapus indeks yang tidak lagi dibutuhkan.
Rekomendasi indeks majemuk
Untuk kueri gabungan pada beberapa bidang, urutan bidang dalam kueri tidak masalah. Anda hanya membutuhkan satu indeks. Sebagai contoh, untuk kueri pada bidang `a` dan `b`, Anda hanya membutuhkan salah satu indeks
{a:1, b:1}atau{b:1, a:1}.Indeks redundan dapat disebabkan oleh hubungan inklusif. Sebagai contoh, kueri berikut digunakan:
db.myCol.find({"b": 2, "c": 3})db.myCol.find({"a": 1, "b": 2, "c": 3})
Kueri kedua berisi semua bidang dari kueri pertama. Anda dapat menggunakan satu indeks untuk memenuhi kedua kueri. Untuk melakukannya, letakkan bidang kueri yang lebih spesifik di awal indeks. Indeksnya harus
{b: 1, c: 1, a: 1}.Indeks redundan dapat disebabkan oleh kombinasi indeks unik dan bidang lainnya. Sebagai contoh, kueri berikut digunakan:
db.myCol.find({"a": 1, "b": 1})db.myCol.find({"a": 1, "c": 1})
Jika bidang `a` memiliki nilai unik, membuat indeks gabungan pada bidang lain selain `a` tidak berguna untuk kueri ini. Anda hanya perlu membuat indeks pada
{a: 1}.
Rekomendasi indeks non-ekuivalen
Jangan buat indeks kueri komposit non-ekuivalen untuk beberapa kueri. Contoh:
db.myCol.find({"a": {$gte: 1} , "b": {$lte: 1}})Dalam kueri non-ekuivalen dengan beberapa bidang ini, hanya bidang paling kiri yang dapat diindeks. Artinya, hanya bidang a yang diindeks. Cukup buat indeks untuk bidang a.
Anda dapat menggunakan kombinasi kueri ekuivalen dan non-ekuivalen. Contoh:
db.myCol.find({"a": {$gte: 1} , "b": 1})Dalam hal ini, indeks optimal harus memiliki bidang kueri kesetaraan terlebih dahulu. Anda harus membuat indeks
{b: 1, a: 1}.
Rekomendasi indeks kueri tipe $or
Kueri tipe $or memerlukan pembuatan indeks untuk setiap kondisi. Contoh:
db.myCol.find({$or: [{"a": 1, "b": 1}, {"c": 1, "d": 1}]})
Anda perlu membuat indeks optimal untuk setiap klausa dalam kueri $or. Untuk kueri {$or: [{"a": 1, "b": 1}, {"c": 1, "d": 1}]}, Anda harus membuat dua indeks terpisah, {a: 1, b: 1} dan {c: 1, d: 1}, bukan indeks gabungan tunggal yang mencakup semua bidang, seperti {a: 1, b: 1, c: 1, d: 1}.
Rekomendasi indeks kueri sortir
Cukup buat indeks untuk kueri sortir berbeda yang berisi bidang yang sama. Contoh:
db.myCol.find({}).sort({"a":1})db.myCol.find({}).sort({"a":-1})
Anda hanya perlu membuat indeks
{a: 1}.Anda dapat menggunakan kueri sortir multi-bidang. Contoh:
db.myCol.find({}).sort({"a":1, "b": -1})Indeks
{a: 1, b: 1}tidak efektif untuk kueri ini. Anda harus membuat indeks{a: 1, b: -1}.Anda dapat menggunakan kombinasi kueri ekuivalen, non-ekuivalen, dan sortir. Contoh:
db.myCol.find({"a": 1, "b": 2, "c": {$gte: 1}}).sort({"d": 1, "e": -1})Urutan bidang dalam indeks harus
equality->sort->non-equality. Sebagai contoh, indeksnya adalah{a: 1, b: 1, d: 1, e: -1, c: 1}.Anda dapat menggunakan kombinasi kueri tipe $or dan sortir. Contoh:
db.myCol.find({$or: [{"a": 1, "b": 1}, {"c": 1, "d": 1}]}).sort({"e": -1})Kueri ini dapat dibagi menjadi dua kueri:
db.myCol.find({"a": 1, "b": 1}).sort({"e":-1})dandb.myCol.find({"c": 1, "d": 1}).sort({"e":-1}). Mengikuti aturan untuk menggabungkan kueri kesetaraan dan sort, Anda harus membuat indeks{a: 1, b: 1, e: -1}dan{c: 1, d: 1, e: -1}.
Gunakan pemetaan untuk mendapatkan hanya bidang yang diperlukan
Jika hanya membutuhkan beberapa bidang dalam dokumen, gunakan pemetaan untuk mendapatkan hanya bidang yang diperlukan demi performa yang lebih baik.
Sebagai contoh, jika hanya membutuhkan bidang timestamp, title, author, dan abstract dalam kueri untuk koleksi posts, jalankan perintah kueri berikut:
db.posts.find( {}, { timestamp : 1 , title : 1 , author : 1 , abstract : 1} ).sort( { timestamp : -1 } )
Gunakan hint() untuk mendapatkan indeks tertentu
Dalam kebanyakan kasus, pengoptimal kueri memilih indeks optimal untuk suatu operasi. Namun, Anda juga dapat menggunakan metode hint() untuk memaksa MongoDB menggunakan indeks tertentu.
Sebagai contoh, Anda dapat menggunakan hint() untuk pengujian performa atau untuk kueri di mana Anda harus memilih bidang yang termasuk dalam beberapa indeks.
Gunakan indeks parsial
Gunakan indeks parsial untuk mengurangi ukuran dan overhead performa indeks. Indeks yang dibuat hanya berisi bidang yang dapat dikueri.
Sebagai contoh, sebuah koleksi berisi bidang a, b, c. Jika kondisi kueri Anda hanya mencakup bidang a, buat indeks hanya pada bidang a.