Catatan: Jawaban ini didasarkan pada MongoDB 3.2.4.
Sebaiknya temukan penggunaan explain()
di MongoDB. explain()
keluaran kueri (mis. db.collection.explain().find(...) ) memungkinkan Anda memeriksa indeks mana yang digunakan dalam kueri, dan menggunakan db.collection.explain('executionStats')
juga akan menunjukkan kepada Anda apakah kueri berhasil atau gagal karena SORT . dalam memori batasan.
$dalam
Sebuah $in kueri dapat dianggap sebagai serangkaian kueri kesetaraan. Misalnya, {a: {$in: [1,3,5]}} dapat dianggap sebagai {a:1}, {a:3}, {a:5} . MongoDB akan mengurutkan $in array sebelum melanjutkan dengan kueri, sehingga {$in: [3,5,1]} tidak berbeda dengan {$in: [1,3,5]} .
Mari kita asumsikan koleksi memiliki indeks
{a:1, b:1}
-
Mengurutkan menurut
adb.coll.find({a: {$in: [1,3,5]}}).sort({a:1})MongoDB akan dapat menggunakan
{a:1,b:1}index, karena kueri ini dapat dianggap sebagai gabungan dari{a:1}, {a:3}, {a:5}pertanyaan. Mengurutkan menurut{a:1}memungkinkan penggunaan awalan indeks , jadi MongoDB tidak perlu melakukan pengurutan di dalam memori.Situasi yang sama juga berlaku untuk kueri:
db.coll.find({a: {$in: [1,3,5]} ,b:{$gte:1, $lt:2}}).sort({a:1})sejak
sort({a:1})juga menggunakan awalan indeks (adalam hal ini),SORT. dalam memori panggung karena itu tidak diperlukan. -
Mengurutkan menurut
bIni adalah kasus yang lebih menarik dibandingkan dengan mengurutkan berdasarkan
a. Misalnya:db.coll.find({a: {$in: [1,3,5]}}).sort({b:1})explain()output dari kueri ini akan memiliki tahap yang disebutSORT_MERGE. Ingat bahwafind()bagian dari kueri dapat dianggap sebagai{a:1}, {a:3}, {a:5}.Kueri
db.coll.find({a:1}).sort({b:1})tidak perlu memilikiSORTdalam memori panggung karena sifat{a:1,b:1}index:yaitu, MongoDB dapat dengan mudah menjalankan indeks (diurutkan) dan mengembalikan dokumen yang diurutkan berdasarkanbsetelah memenuhi parameter kesetaraan padaa. Misalnya, untuk setiapa, ada banyakbyang sudah diurutkan berdasarkanbkarena indeks.Menggunakan
$in, kueri keseluruhan dapat dianggap sebagai:db.coll.find({a:1}).sort({b:1})db.coll.find({a:3}).sort({b:1})db.coll.find({a:5}).sort({b:1})- Ambil hasil kueri individual di atas, dan lakukan penggabungan menggunakan nilai
b. Kueri tidak memerlukan tahap pengurutan dalam memori karena hasil kueri individual sudah diurutkan berdasarkanb. MongoDB hanya perlu menggabungkan hasil sub-kueri (yang sudah diurutkan) menjadi satu hasil.
Demikian pula, kueri
db.coll.find({a: {$in: [1,3,5]} ,b:{$gte:1, $lt:2}}).sort({b:1})juga menggunakan
SORT_MERGEstage dan sangat mirip dengan query di atas. Perbedaannya adalah bahwa setiap kueri menghasilkan dokumen berdasarkan rentangb(bukan setiapb) untuk setiapa(yang akan diurutkan berdasarkanbkarena indeks{a:1,b:1}). Oleh karena itu, kueri tidak memerlukan tahap pengurutan dalam memori.
$atau
Untuk $or permintaan untuk menggunakan indeks, setiap klausa di $or ekspresi harus memiliki indeks yang terkait dengannya
. Jika persyaratan ini dipenuhi, kueri mungkin menggunakan SORT_MERGE panggung seperti $in pertanyaan. Misalnya:
db.coll.explain().find({$or:[{a:1},{a:3},{a:5}]}).sort({b:1})
akan memiliki rencana kueri yang hampir identik, penggunaan indeks, dan SORT_MERGE stage seperti pada $in contoh di atas. Pada dasarnya, kueri dapat dianggap sebagai:
db.coll.find({a:1}).sort({b:1})db.coll.find({a:3}).sort({b:1})db.coll.find({a:5}).sort({b:1})- Ambil hasil kueri individual di atas, dan lakukan penggabungan menggunakan nilai
b.
seperti $in contoh sebelumnya.
Namun, kueri ini:
db.coll.explain().find({$or:[{a:1},{b:1}]}).sort({b:1})
tidak dapat menggunakan indeks apa pun (karena kami tidak memiliki {b:1} indeks). Kueri ini akan menghasilkan pemindaian koleksi, dan akibatnya akan memiliki tahap pengurutan dalam memori karena tidak ada indeks yang digunakan.
Namun, jika kita membuat indeks {b:1} , kueri akan dilanjutkan seperti:
db.coll.find({a:1}).sort({b:1})db.coll.find({b:1}).sort({b:1})- Ambil hasil kueri individual di atas, dan lakukan penggabungan menggunakan nilai
b(yang sudah diurutkan di kedua sub-kueri, karena indeks{a:1,b:1}dan{b:1}).
dan MongoDB akan menggabungkan hasil {a:1} dan {b:1} kueri dan melakukan penggabungan pada hasil. Proses penggabungan adalah waktu linier, mis. O(n) .
Kesimpulannya, dalam $or query, setiap istilah harus memiliki indeks, termasuk sort() panggung. Jika tidak, MongoDB harus melakukan pengurutan dalam memori.