Indeks MongoDB adalah kunci untuk mendapatkan kinerja yang konsisten pada koleksi MongoDB yang besar. Tapi MongoDB memperingatkan itu. Jadi berapa banyak yang "terlalu banyak"? Show
Kesimpulan yang disajikan dalam artikel ini adalah hasil percobaan N=1. Mereka tidak dijamin benar di semua mesin dan lingkungan. Selain itu, saya tidak berbicara untuk MongoDB, kesimpulan ini tidak mewakili pedoman resmi MongoDB Apa itu Indeks?Misalkan Anda menjalankan kueri berikut menggunakan Mongoose
Tanpa indeks apa pun, MongoDB harus menelusuri setiap dokumen dalam koleksi Jika Anda memiliki 10 pengguna, memindai seluruh koleksi tidak menjadi masalah. Jika Anda memiliki 10 juta pengguna, memindai seluruh koleksi mungkin menjadi masalah jika Anda harus sering menjalankan kueri ini Indeks pada Misalnya, Anda memiliki 120 ribu dokumen dengan nama depan dan nama belakang yang sama, lalu 1 dokumen dengan nama belakang berbeda. Tanpa indeks, ada penundaan yang nyata dalam menemukan dokumen dengan nama belakang yang berbeda Tetapi dengan indeks, kueri yang sama dijalankan hampir secara instan Kapan Anda Membutuhkan Indeks?Dalam pengalaman saya, indeks tidak berguna untuk koleksi kecil. Saya berpendapat bahwa jika koleksi memiliki kurang dari 10 ribu dokumen, indeks tidak memberi Anda banyak manfaat. Itu karena pemindaian koleksi hampir seketika pada 10k koleksi dokumen, dengan asumsi database tidak dalam beban tinggi Dengan indeks, kueri secara signifikan lebih cepat dalam persentase, tetapi tidak secara absolut. Jika titik akhir API hanya mengeksekusi kueri Aturan umum saya saat membangun API. jika koleksi memiliki kurang dari 10k dokumen, jangan repot-repot mengindeks. Jika koleksi memiliki lebih dari 100 ribu dokumen, pastikan kueri umum menggunakan indeks Contoh Terlalu Banyak IndeksIndeks memang bagus, tetapi terlalu banyak indeks dapat menyebabkan penulisan lebih lambat. Itu karena MongoDB juga perlu memperbarui indeks saat Anda memperbarui dokumen Misalnya, Anda memiliki 1000 properti yang diindeks, dan Anda mengirim Bagaimana kinerja berubah saat Anda men-tweak jumlah indeks Hal yang perlu diperhatikan di sini adalah jika Anda memiliki 100 indeks atau kurang, penalti kinerja untuk penulisan sangat minim. Jika koleksi Anda memiliki 5 indeks, kinerja tulis Anda tidak akan terlalu terpengaruh jika Anda menambahkan indeks ke-6. Performa tulis hanya mulai menurun secara nyata ketika Anda harus memperbarui ratusan indeks saat menulis Perhatikan bahwa contoh ini mengasumsikan bahwa indeks Anda sesuai dengan RAM. Jika indeks Anda tidak sesuai dengan RAM, Anda mungkin dikenakan penalti kinerja yang lebih tinggi untuk indeks tambahan BergerakMongoDB memiliki kinerja yang luar biasa, dan saya tidak akan membuat aplikasi di atas yang lain. Dengan menerapkan beberapa pola desain skema, berhati-hati dengan operasi lambat yang diketahui, dan menyiapkan indeks yang tepat, Anda dapat dengan mudah menangani koleksi yang berisi puluhan juta dokumen. Di Booster, setiap sen dari pendapatan tahunan $50 juta+ kami disalurkan melalui satu klaster MongoDB yang tidak di-shard yang berjalan di VM cloud sederhana - semuanya berkat strategi pengindeksan yang baik Ingin menjadi ahli MongoDB tim Anda? . Itu berarti Anda dapat mempelajari apa yang perlu Anda ketahui untuk membuat aplikasi full-stack siap produksi dengan Node. js dan MongoDB dalam beberapa hari. Dapatkan salinan Anda Perbedaan antara aplikasi Anda yang cepat, responsif, dan penskalaan dengan benar seringkali bergantung pada cara Anda menggunakan indeks di database. MongoDB tidak berbeda, kinerjanya (dan keseluruhan kinerja aplikasi Anda) sangat bergantung pada mendapatkan jumlah indeks yang tepat pada hal yang benar. Satu atau dua indeks sederhana dapat mempercepat pengambilan data dari MongoDB jutaan kali lipat untuk tabel jutaan catatan. Tetapi pada saat yang sama memiliki terlalu banyak indeks pada koleksi besar dapat menyebabkan penurunan besar-besaran dalam kinerja secara keseluruhan. Anda perlu mendapatkan indeks Anda dengan benar Untuk blog ini, kita akan berbicara tentang memiliki terlalu banyak indeks dan membantu Anda menemukan indeks duplikat dan tidak terpakai. Jika Anda tertarik untuk mengetahui apakah Anda memerlukan indeks tambahan atau jika kueri Anda menggunakan indeks, saya sarankan membaca artikel Percona sebelumnya tentang penyetelan kueri (Bagian 1 & Bagian 2 dari seri itu) Jadi, indeks sangat bagus untuk mendapatkan kueri yang lebih cepat. Berapa banyak indeks yang harus saya buat pada koleksi? Masalah Kinerja UmumSetelah menganalisis banyak lingkungan MongoDB yang berbeda, saya dapat memberikan daftar berikut yang meringkas kesalahan umum yang saya lihat
Saya tidak mempertimbangkan kasus pertama. Saya akan membahas yang kedua Berapa Banyak Indeks yang Anda Butuhkan dalam KoleksiItu tergantung - itu jawaban yang tepat. Pada dasarnya, itu tergantung pada beban kerja aplikasi Anda. Anda harus mempertimbangkan aturan berikut saat mengindeks koleksi
Apa? . Nah, kita bisa meringkas hanya dalam satu aturan sederhana
Itu dia Pro dan Kontra PengindeksanKeuntungan besar dari indeks adalah memungkinkan kueri, pembaruan, dan penghapusan berjalan secepat mungkin jika digunakan. (Setiap pembaruan atau penghapusan juga perlu melakukan langkah pencarian terlebih dahulu). Lebih banyak indeks dalam koleksi dapat menguntungkan beberapa kueri Sayangnya, indeks membutuhkan kerja ekstra untuk MongoDB. Setiap kali Anda menjalankan penulisan, semua indeks harus diperbarui. Nilai-nilai baru disimpan atau dijatuhkan ke dalam struktur B-Tree, beberapa pemisahan atau penggabungan diperlukan, dan ini membutuhkan waktu Masalah utama adalah bahwa "lebih banyak indeks yang Anda miliki dalam koleksi, semakin lambat semua penulisan" Koleksi yang sangat besar dengan hanya 10 atau 15 indeks dapat menyebabkan penurunan performa yang signifikan untuk penulisan. Juga, ingat bahwa indeks harus disalin ke dalam cache WiredTiger. Lebih banyak indeks juga menyiratkan lebih banyak tekanan untuk cache memori. Tekanan kemudian dapat menyebabkan lebih banyak pengusiran dan kelambatan cache Contoh bagusnya adalah ketika saya bekerja dengan pelanggan beberapa minggu yang lalu kami menemukan 12 indeks tambahan pada koleksi yang tidak mereka perlukan. Koleksinya sekitar 80GB; . Mereka memiliki beban tulis yang relevan berdasarkan beberapa penyisipan dan pembaruan yang sering dilakukan setiap saat. Membersihkan indeks ini meningkatkan waktu eksekusi kueri tulis rata-rata sebesar 25-30 persen. Peningkatan yang diamati untuk kasus nyata ini tidak akan menjadi jumlah kuantitatif yang sama dalam kasus lain, tetapi yang pasti semakin sedikit indeks yang Anda miliki, semakin cepat semua penulisan akan dilakukan. Kita perlu menemukan semacam keseimbangan. membuat lebih banyak indeks, tetapi tidak sebanyak itu Cara Mengurangi Over-IndexingSangat mudah untuk mengatakannya. jatuhkan semua indeks yang tidak Anda butuhkan Ada dua hal yang dapat Anda lakukan untuk mengidentifikasi indeks yang akan dijatuhkan
Untuk menjatuhkan indeks, Anda perlu menjalankan sesuatu seperti berikut ini Kerang1 db. koleksi saya. dropIndex("nama_indeks") Temukan Indeks DuplikatIndeks duplikat bisa berupa indeks dengan definisi yang persis sama dengan indeks lain yang sudah ada dalam koleksi. Untungnya, MongoDB dapat memeriksa ini dan tidak diizinkan membuat indeks semacam itu Mari kita lakukan pengujian menggunakan koleksi sederhana tanpa indeks Kerang1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 rs_test. UTAMA> db. tes. temukan() { "_id" . ObjectId("60521309d7268c122c7cd630"), "name" : "corrado", "usia" . 49 } { "_id" . ObjectId("60521313d7268c122c7cd631"), "name" : "simone", "usia" . 12 } { "_id" . ObjectId("6052131cd7268c122c7cd632"), "name" : "gabriele", "umur" . 19 } { "_id" . ObjectId("60521323d7268c122c7cd633"), "name" : "luca", "umur" . 14 } { "_id" . ObjectId("60521328d7268c122c7cd634"), "name" : "lucia", "umur" . 49 }
# buat indeks pada bidang nama rs_test. UTAMA> db. tes. createIndex( { nama. 1 } ) { "dibuatKoleksiOtomatis" . salah, "numIndexesBefore" . 1, "numIndexesAfter" . 2, "commitQuorum" . "memilih Anggota", "oke" . 1, "$clusterTime" . { "clusterTime" . Stempel waktu(1615991942, 5), "tanda tangan" . { "hash" . BinData(0,"), "keyId" . NumberLong("6890926313742270469") } }, "Waktu Operasi" . Stempel waktu(1615991942, 5) }
# periksa indeks tersedia rs_test. UTAMA> db. tes. getIndex() [ { "v" . 2, "kunci" . { "_id" . 1 }, "nama" . "_id_" }, { "v" . 2, "kunci" . { "nama" . 1 }, "nama" . "nama_1" } ]
# coba buat lagi indeks yang sama rs_test. UTAMA> db. tes. createIndex( { nama. 1 } ) { "numIndexesBefore" . 2, "numIndexesAfter" . 2, "catatan" . "semua indeks sudah ada", "oke" . 1, "$clusterTime" . { "clusterTime" . Stempel waktu(1615991942, 5), "tanda tangan" . { "hash" . BinData(0,"), "keyId" . NumberLong("6890926313742270469") } }, "Waktu Operasi" . Stempel waktu(1615991942, 5) }
# hebat, MongoDB dapat mendeteksi indeks yang sudah ada
# mari kita coba untuk melihat apakah Anda dapat membuat indeks yang sama dengan nama yang berbeda rs_test. UTAMA> db. tes. createIndex( { nama. 1 }, { nama . : "this_is_a_different_index_name" } ) { "Waktu Operasi" . Stempel waktu(1615991981, 1), "oke" . 0, "errmsg" . "Indeks dengan nama. this_is_a_different_index_name sudah ada dengan nama yang berbeda", "kode" . 85, "codeName" . "IndexOptionsConflict", "$clusterTime" . { "clusterTime" . Stempel waktu(1615991981, 1), "tanda tangan" . { "hash" . BinData(0,"), "keyId" . NumberLong("6890926313742270469") } } }
# bahkan dalam hal ini MongoDB tidak mengizinkan pembuatan indeks MongoDB kemudian cukup pintar untuk menghindari pembuatan indeks duplikat. Tapi bagaimana dengan pembuatan indeks yang merupakan awalan kiri dari indeks yang ada? Kerang1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 # mari kita jatuhkan indeks sebelumnya yang telah kita buat rs_test. UTAMA> db. tes. dropIndex( "nama_1" ) { "nIndexesWas" . 2, "oke" . 1, "$clusterTime" . { "clusterTime" . Stempel waktu(1615993029, 1), "tanda tangan" . { "hash" . BinData(0,"), "keyId" . NumberLong("6890926313742270469") } }, "Waktu Operasi" . Stempel waktu(1615993029, 1) }
# periksa indeks. Hanya _id yang tersedia rs_test. UTAMA> db. tes. getIndex() [ { "v" . 2, "kunci" . { "_id" . 1 }, "nama" : "_id_" } ]
# buat indeks majemuk rs_test. UTAMA> db. tes. createIndex( { nama. 1, umur. 1 } ) { "dibuatKoleksiOtomatis" . salah, "numIndexesBefore" . 1, "numIndexesAfter" . 2, "commitQuorum" . "memilih Anggota", "oke" . 1, "$clusterTime" . { "clusterTime" . Stempel waktu(1615993054, 5), "tanda tangan" . { "hash" . BinData(0,"), "keyId" . NumberLong("6890926313742270469") } }, "Waktu Operasi" . Stempel waktu(1615993054, 5) }
# buat indeks lain yang merupakan awalan paling kiri dari indeks majemuk rs_test. UTAMA> db. tes. createIndex( { nama. 1 } ) { "dibuatKoleksiOtomatis" . salah, "numIndexesBefore" . 2, "numIndexesAfter" . 3, "commitQuorum" . "memilih Anggota", "oke" . 1, "$clusterTime" . { "clusterTime" . Stempel waktu(1615993060, 5), "tanda tangan" . { "hash" . BinData(0,"), "keyId" . NumberLong("6890926313742270469") } }, "Waktu Operasi" . Stempel waktu(1615993060, 5) }
# periksa indeks rs_test. UTAMA> db. tes. getIndex() [ { "v" . 2, "kunci" . { "_id" . 1 }, "nama" . "_id_" }, { "v" . 2, "kunci" . { "nama" . 1, "usia" . 1 }, "nama" . "nama_1_umur_1" }, { "v" . 2, "kunci" . { "nama" . 1 }, "nama" . "nama_1" } ] Kami juga menganggap indeks awalan paling kiri sebagai duplikat Untuk memanfaatkan indeks majemuk MongoDB tidak perlu menggunakan semua bidang indeks itu, awalan paling kiri sudah cukup. Misalnya indeks pada (A,B,C) dapat digunakan untuk memenuhi kombinasi (A), (A,B), (A,B,C) tetapi tidak (B) atau (B,C). Akibatnya, jika saya memiliki dua indeks berbeda, satu di (A, B, C) dan satu lagi di (A, B), yang kedua adalah duplikat karena yang pertama dapat digunakan dengan cara yang sama untuk menyelesaikan kueri dengan Kemudian, temukan semua indeks duplikat dan jatuhkan karena tidak berguna. Berhati-hatilah dan periksa apakah aplikasi Anda tidak menggunakan petunjuk () pada indeks yang akan Anda jatuhkan Untuk menghindari pemeriksaan manual semua koleksi untuk menemukan duplikatnya, saya berikan di sini kode javascript untuk itu Kerang1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 var ldb = db. adminCommand( { daftarDatabase. 1 } );
untuk ( i = 0; i < ldb.databases. panjang; i ++ ) {
jika ( ldb. database[i]. nama . = 'admin' && ldb. database[i]. nama. = 'konfigurasi' && ldb. database[i]. nama. = 'lokal') {
print('DATABASE',ldb. database[i]. nama); cetak("+++++++++++++++)
var db = db.getSiblingDB(ldb. database[i]. nama); var cpd = db.getCollectionNames();
untuk ( j = 0; j < cpd.length; j ++ ) {
jika ( cpd[j] ! = 'sistem. profile' ) {
var indeks = JSON.parse(JSON. merangkai(db. runCommand( { indeksdaftar. cpd[j] } . kursor ).cursor. gelombang pertama)); cetak("KUMPULKAN. " + cpd[j]);
untuk ( k = 0; k < indexes.length; k ++ ) {
indeks[k] = (((JSON.stringify(indeks[k . kunci.key)). ganti("{","")).replace("}","")).replace( / , / g ,"_");
}
var ditemukan = salah;
untuk ( k1 = 0; k1 < indexes.length; k1 ++ ) {
untuk ( k2 = 0; k2 < indexes.length; k2 ++ ) {
jika ( k1 . = k2 ) {
if (indeks[k1].startsWith(indeks[k2],0)) {
cetak("{ " + indexes[k2]+" } is the left prefix of { "+indexes[k1]+" } and should be dropped");
ditemukan = benar;
} } } }
jika (. ditemukan) {
cetak("tidak ada indeks duplikat yang ditemukan");
}
cetak("\n");
} }
cetak("\n"); } } Catatan. skrip ini hanyalah pengujian awal dan dapat ditingkatkan, tetapi seharusnya berfungsi dalam banyak kasus Temukan Indeks yang Tidak DigunakanMongoDB memelihara statistik internal tentang penggunaan indeks. Setiap kali indeks digunakan untuk menyelesaikan kueri, penghitung tertentu adalah kenaikan. Setelah menjalankan MongoDB untuk waktu yang cukup lama – berhari-hari atau berminggu-minggu – statistiknya dapat diandalkan dan kami dapat mengetahui indeks mana yang telah digunakan atau tidak Untuk melihat statistik indeks, MongoDB menyediakan tahapan dalam pipa agregasi. $indexStats Di sini Anda dapat melihat contohnya Kerang1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 rs_test. UTAMA> db. restoran. agregat([ { $ . : {} } ]) . cantik.pretty() { "nama" . "borough_1", "kunci" . { "wilayah" . 1 }, "host" . "ip-172-30-2-12. 27017", "mengakses" . { "ops" . NumberLong(312), "sejak" . Tanggal ISO("2021-03-17T13. 48. 51. 305Z") }, "spek" . { "v" . 2, "kunci" . { "wilayah" . 1 }, "nama" . "borough_1" } } { "nama" . "_id_", "kunci" . { "_id" . 1 }, "host" . "ip-172-30-2-12. 27017", "mengakses" . { "ops" . NumberLong(12), "sejak" . Tanggal ISO("2021-03-17T13. 48. 51. 305Z") }, "spek" . { "v" . 2, "kunci" . { "_id" . 1 }, "nama" . "_id_" } } { "nama" . "cuisine_1_borough_1", "kunci" . { "masakan" . 1, "wilayah" . 1 }, "host" . "ip-172-30-2-12. 27017", "mengakses" . { "ops" . NumberLong(0), "sejak" . Tanggal ISO("2021-03-17T13. 48. 51. 305Z") }, "spek" . { "v" . 2, "kunci" . { "masakan" . 1, "wilayah" . 1 }, "nama" . "cuisine_1_borough_1" } } Akses. ops adalah berapa kali indeks telah digunakan. Dalam contoh Anda dapat melihat { borough. 1 } telah digunakan 312 kali, indeks { _id } 12 kali, dan indeks { masakan. 1, kelurahan. 10 Kali. Yang terakhir bisa dijatuhkan Jika database berjalan lama dengan jutaan kueri dieksekusi dan jika indeks tidak digunakan, kemungkinan besar itu tidak akan digunakan bahkan di masa mendatang Maka Anda harus mempertimbangkan untuk menghapus indeks yang tidak digunakan untuk meningkatkan penulisan, mengurangi tekanan cache, dan juga menghemat ruang disk Dengan menggunakan skrip berikut, Anda dapat mengetahui statistik indeks untuk semua koleksi Kerang1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var ldb = db. adminCommand( { daftarDatabase. 1 } );
for (i = 0; i<ldb.databases. panjang; i ++ ) {
cetak('DATABASE ',ldb.databases[i]. nama);
jika ( ldb. database[i]. nama . = 'admin' && ldb. database[i]. nama. = 'konfigurasi' && ldb. database[i]. nama. = 'lokal' ) {
var db = db. getSiblingDB(ldb. database[i]. nama); var cpd = db.getCollectionNames();
untuk (j = 0; j<cpd.length; j ++ ) {
jika ( cpd[j] ! = 'sistem. profile' ) {
cetak(cpd[j]);
var pui = db.runCommand({ agregat . cpd[j] , . pipeline : [{$indexStats. {}}], . cursor: { batchSize. 100 } }); printjson(pui);
} }
cetak('\n\n'); } } Cari indeks yang memiliki "ops". AngkaPanjang(0) KesimpulanMembuat indeks untuk menyelesaikan kueri adalah kebiasaan yang baik, tetapi berhati-hatilah untuk tidak menyalahgunakan pengindeksan. Pengindeksan yang berlebihan dapat menyebabkan penulisan yang lebih lambat, tekanan berlebihan pada cache memori, dan lebih banyak penggusuran Anda harus mempertimbangkan mempertahankan indeks Anda dari waktu ke waktu membuang semua duplikat dan indeks yang tidak terpakai. Skrip yang disediakan dalam artikel ini dapat membantu analisis indeks Anda Distribusi Percona untuk MongoDB adalah alternatif basis data MongoDB yang tersedia secara gratis, memberi Anda satu solusi yang menggabungkan komponen perusahaan terbaik dan terpenting dari komunitas sumber terbuka, dirancang dan diuji untuk bekerja sama Berapa banyak indeks yang dapat dibuat oleh MongoDB?Satu koleksi dapat memiliki tidak lebih dari 64 indeks .
Berapa banyak indeks yang terlalu banyak MongoDB?Secara umum, sebaiknya batasi koleksi Anda hingga maksimal 50 indeks .
Bisakah kita membuat banyak indeks di MongoDB?MongoDB dapat menggunakan persimpangan beberapa indeks untuk memenuhi kueri . Secara umum, setiap persimpangan indeks melibatkan dua indeks; .
Berapa batas kunci indeks di MongoDB?Satu koleksi tidak boleh memiliki lebih dari 64 indeks |