Last chance! 50% off DataCamp Premium
Sale ends in
Pada basis data apa pun, termasuk MongoDB, indeks adalah bagian penting dari proses pengembangan. Tanpa indeks, seiring ukuran basis data bertambah, performa basis data Anda akan terus menurun. Dengan indeks yang tepat, saat data bertambah, performa akses akan tetap optimal.
Dalam artikel ini, kita akan membahas berbagai jenis indeks yang tersedia di MongoDB, beberapa tips dan trik untuk mendapatkan pengalaman terbaik, serta panduan agar Anda benar-benar memanfaatkan indeks yang Anda buat. Jika Anda masih mempelajari MongoDB, saya sarankan untuk melihat kursus Pengantar MongoDB.
Saat membicarakan indeks, kita membicarakan performa. Indeks adalah pembeda antara memeriksa setiap dokumen dalam sebuah koleksi untuk melihat apakah sesuai dengan kueri kita, atau memeriksa sekumpulan dokumen yang lebih spesifik yang sesuai dengan kueri tersebut. Jika koleksinya kecil dan tidak banyak dokumen yang dipindai, performanya akan baik-baik saja. Namun jika kita memiliki 100.000 dokumen dalam sebuah koleksi dan hanya 100 yang akan cocok dengan kueri, akan memakan waktu untuk menelusuri seluruh 100.000 dokumen guna menemukan 100 tersebut jika tidak ada indeks berdasarkan 100 dokumen itu.
Ada banyak jenis indeks di MongoDB:
_id dapat dianggap sebagai indeks bidang tunggal.Untuk informasi lebih lanjut tentang berbagai jenis indeks, lihat dokumentasi MongoDB.
Sering kali, Anda akan menggunakan indeks bidang tunggal, gabungan, atau multikey, tetapi pada akhirnya, semuanya bergantung pada jenis aplikasi, kueri, dan data.
Indeks penting untuk setiap interaksi basis data yang mengambil dokumen. Ini tidak terbatas pada pengambilan dokumen menggunakan operasi find atau findOne. Saat memperbarui dan menghapus dokumen, Anda juga menggunakan kriteria pencocokan yang akan digunakan basis data untuk menemukan dokumen sebelum melakukan pembaruan atau penghapusan.
Operator find dan findOne bukan satu-satunya operator pengambilan yang dapat memanfaatkan indeks. Saat menggunakan operator $match sebagai tahap pertama pada pipeline agregasi Anda, sebuah indeks akan mempercepat proses secara drastis.
Membuat indeks secara acak bisa sama tidak efisiennya dengan tidak menggunakan indeks di MongoDB. Sebagai gantinya, ada beberapa hal yang perlu dipertimbangkan untuk membantu Anda membangun aplikasi yang jauh lebih efisien.
Aturan praktis saat membuat indeks gabungan adalah menentukan bagaimana Anda akan menggunakan setiap bidang dalam kueri dan memastikan mengikuti praktik terbaik ESR).
Apa arti ESR? Mari kita uraikan:
$lt atau $gt akan mencocokkan dokumen dalam suatu rentang, bukan kecocokan spesifik.Untuk gambaran yang lebih jelas, lihat kueri berikut:
db.employee.find(
{
"department": "Developer Relations",
"salary": {
"$lt": 80000
}
}
).sort(
{
"name": 1
}
);
Kueri di atas melakukan pencocokan equality pada department, pencocokan range pada salary, dan mengurutkan hasil berdasarkan name.
Mengikuti aturan ESR, indeksnya akan terlihat seperti ini:
db.employee.createIndex({
"department": 1,
"name": 1,
"salary": 1
});
Kita ingin mengikuti aturan ESR untuk mencegah pengurutan di memori, dan untuk memperkecil ruang pencarian agar eksekusi kueri lebih bertenaga.
Pengindeksan secara umum akan membuat subset dokumen yang lebih kecil untuk dipindai saat menjalankan kueri dan, sebagai hasilnya, meningkatkan performa. Namun jika Anda ingin membawa performa aplikasi ke tingkat berikutnya, Anda perlu mengeksplorasi covered query. Dengan covered query, semua hasil kueri Anda didapat langsung dari indeks, tanpa harus memindai dokumen apa pun dalam koleksi.
Ada beberapa catatan di sini yang mungkin membuat covered query bisa atau tidak bisa digunakan di aplikasi Anda:
Jadi, apa artinya semua ini?
Ambil contoh indeks berikut:
db.department.createIndex({
"country": 1,
"salary": 1
});
Pada contoh di atas, kita ingin dokumen diindeks berdasarkan bidang country dan bidang salary. Lalu, kita dapat menjalankan kueri berikut:
db.department.find(
{
"country": "US"
},
{
"country": 1,
"salary": 1
}
);
Kueri di atas, yang menyertakan proyeksi, akan menggunakan indeks kita, tetapi bukan covered query. Bidang _id dikembalikan secara default di MongoDB dan dalam contoh ini, bidang _id tidak pernah ditambahkan ke indeks kita. Jadi kita bisa mengubah indeks, atau mengubah kuerinya. Pada contoh mengubah kueri, kita bisa melakukan ini:
db.department.find(
{
"country": "US"
},
{
"country": 1,
"salary": 1,
"_id": 0
}
);
Ingat, jika Anda ingin menggunakan covered query, indeks harus valid dan bidang-bidang yang diminta harus termasuk dalam indeks. Jika tidak, Anda hanya menemukan dokumen yang dikelola oleh indeks, bukan di dalam indeks itu sendiri.
Anda dapat memvalidasi apakah covered query digunakan atau tidak dengan memanfaatkan argumen executionStats pada operator explain yang dibahas lebih lanjut di artikel ini. Hasil totalDocsExamined akan menentukan apa yang digunakan. Jika nilainya nol, Anda menggunakan covered query.
Indeks tidak gratis dalam konteks sumber daya server. Setiap indeks harus dipelihara oleh server dan pemeliharaan ini menggunakan sumber daya CPU, RAM, dan disk. Saat Anda membuat lebih banyak indeks, Anda akan menambah overhead yang dapat mengakibatkan biaya lebih tinggi atau penurunan performa pada skenario server yang kurang diprovsi. Penurunan performa ini bisa menjalar ke operasi tulis dan hapus, bukan hanya baca, karena MongoDB mengonsumsi lebih banyak sumber daya.
Sebaiknya hanya membuat indeks untuk kueri berfrekuensi tinggi. Apakah kueri yang dijalankan sebulan sekali benar-benar memerlukan indeks? Mungkin tidak. Apakah kueri yang dijalankan setiap 10 detik memerlukan indeks? Tentu saja!
Pelajari beberapa praktik terbaik pengindeksan lainnya di Blog MongoDB.
Hanya karena Anda telah membuat indeks di MongoDB bukan berarti kueri yang Anda jalankan benar-benar menggunakannya. Di MongoDB, kita bisa menelusuri indeks mana yang digunakan untuk kueri tertentu.
Ambil contoh indeks berikut:
db.people.createIndex({
"name": 1,
"is_active": 1
});
Pada contoh di atas, kita membuat indeks pada bidang name dan bidang is_active. Sekarang, kita ingin menjalankan kueri berikut:
db.people.find({
"is_active": true
});
Kueri di atas akan berjalan dengan atau tanpa indeks yang valid, dan jika datasetnya kecil, akan tetap berjalan cepat. Namun, jika kita ingin melihat apakah indeks kita digunakan, kita bisa menyesuaikan kuerinya:
db.people.find({
"is_active": true
}).explain();
Kali ini, kita menggunakan metode explain untuk mendapatkan rencana eksekusi kueri. Dalam rencana eksekusi, kita dapat melihat hal berikut:
winningPlan: {
isCached: false,
stage: 'COLLSCAN',
filter: { is_active: { '$eq': true } },
direction: 'forward'
}
Untuk kueri ini, MongoDB menggunakan "COLLSCAN" yang berarti tidak memanfaatkan indeks kita meskipun menyertakan salah satu bidang indeks. Jika kita mengubah kueri menjadi seperti ini:
db.people.find({
"name": "Nic Raboy",
"is_active": true
}).explain();
Hasil explain kita berubah:
winningPlan: {
isCached: false,
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
keyPattern: { name: 1, is_active: 1 },
indexName: 'name_1_is_active_1',
isMultiKey: false,
multiKeyPaths: { name: [], is_active: [] },
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
name: [ '["Nic Raboy", "Nic Raboy"]' ],
is_active: [ '[true, true]' ]
}
}
},
Kali ini, rencana eksekusi menunjukkan kita menggunakan "IXSCAN" dan menyebutkan nama indeks yang digunakan, yaitu indeks name_1_is_active_1. Namanya ditentukan secara otomatis saat kita membuat indeks.
Untuk operasi update, prosesnya serupa dengan pengecualian pada penempatan fungsi explain.
Operasi update mungkin terlihat seperti berikut:
db.people.explain().update(
{
“name”: “Nic Raboy”,
“Is_active”: true
},
{
“$set”: { “is_active”: false }
}
);
Perhatikan bahwa pada contoh di atas, explain dilakukan sebelum fungsi update.
Jika Anda menggunakan indeks yang diharapkan pada operasi update, Anda akan melihat nilai "IXSCAN" beserta nama indeksnya. Temukan informasi lebih lanjut tentang operasi update dan penggunaan indeks di dalamnya.
Metode alternatif untuk mengetahui detail rencana eksekusi kueri Anda adalah dengan menggunakan runCommand pada basis data. Meskipun tampilannya tidak begitu elegan, metode ini sangat kuat dan akan terlihat seperti berikut:
db.runCommand({
"explain": {
"update": "people",
"updates": [
{
"q": {
"name": "Nic Raboy",
"is_active": true
},
"u": {
"$set": { "is_active": false }
}
}
]
},
"verbosity": "allPlansExecution"
});
Contoh di atas akan bekerja sama seperti operasi update dengan fungsi explain.
Jika Anda belum yakin dalam membuat indeks, atau Anda melihat kueri berjalan lebih lambat dari yang diharapkan, pertimbangkan untuk memeriksa detail eksekusinya.
Anda baru saja melihat beberapa praktik terbaik terkait pengindeksan di MongoDB. Meskipun kita tidak mengeksplorasi semua skenario pengindeksan yang mungkin, Anda dapat menggunakan ini sebagai titik awal untuk memastikan pengguna mendapatkan pengalaman terbaik saat bekerja dengan data Anda.
Menegaskan kembali beberapa hal:
explain untuk menguji indeks dan performanya.Poin-poin di atas bukanlah daftar lengkap praktik terbaik pengindeksan yang akan meningkatkan performa aplikasi Anda. Ada faktor lain, seperti jumlah kardinalitas.
Untuk bantuan lebih lanjut terkait pengindeksan, lihat dokumentasi MongoDB. Jika Anda menggunakan tier berbayar di MongoDB Atlas, pertimbangkan untuk menggunakan beberapa alat performance adviser bawaan untuk rekomendasi indeks dan kueri.
Tergantung. Anda perlu menemukan keseimbangan yang sesuai, tetapi pertimbangkan untuk mengindeks hanya kueri yang dieksekusi sering dibandingkan yang sesekali.
Apakah Anda yakin kueri Anda benar-benar menggunakan indeks yang telah Anda buat? Gunakan operator explain atau beberapa alat advisor di MongoDB Atlas untuk penelusuran masalah.
Meskipun MongoDB terkadang dapat menggunakan indeks di luar urutan, indeks paling efektif saat urutan kunci indeks sesuai dengan urutan kueri: pertama filter equality, lalu sort, dan terakhir range.
Secara default, explain() berjalan dalam mode “queryPlanner”, tetapi jika Anda ingin mode lain, tersedia juga mode “executionStats” dan “allPlansExecution”.

Nic Raboy adalah Pimpinan Developer Relations di MongoDB, memimpin tim pengembang Python, Java, C#, dan PHP yang membuat konten luar biasa untuk membantu para pengembang berhasil mengintegrasikan MongoDB ke dalam proyek mereka. Ia berpengalaman dengan Golang dan JavaScript dan sering menulis tentang berbagai petualangan pengembangannya.
Kursus Teratas DataCamp
{count, plural, one {Kursus} other {Kursus}}
{count, plural, one {Kursus} other {Kursus}}
{count, plural, one {blog} other {blogs}}
Dario Radečić
15 mnt
{count, plural, one {blog} other {blogs}}
David Woods
13 mnt

{count, plural, one {blog} other {blogs}}
Javier Canales Luna
14 mnt
{count, plural, one {blog} other {blogs}}
Hugo Bowne-Anderson
13 mnt