Dari MongoDB
dokumentasi disebutkan bahwa:
Saat Anda hanya membutuhkan sebagian bidang dari dokumen, Anda dapat mencapai kinerja yang lebih baik dengan mengembalikan hanya bidang yang Anda butuhkan
Bagaimana bidang pemfilteran memengaruhi kinerja? Apakah kinerja terkait dengan ukuran data yang dikirim melalui jaringan? atau ukuran data yang akan disimpan dalam memori? Bagaimana tepatnya kinerja ini ditingkatkan? Apa kinerja ini yang disebutkan dalam dokumentasi?
Saya memiliki pertanyaan MongoDB yang lambat. Apakah mengembalikan subset mempengaruhi permintaan lambat saya (saya memiliki indeks gabungan di lapangan)?
mongodb
projection
ALH
sumber
sumber
Debian 8
,MongoDB 3.6.2
Jawaban:
Secara default, kueri mengembalikan semua bidang dalam dokumen yang cocok. Jika Anda membutuhkan semua bidang, mengembalikan dokumen lengkap akan lebih efisien daripada meminta server memanipulasi hasil yang ditetapkan dengan kriteria proyeksi.
Namun, menggunakan proyeksi untuk membatasi bidang untuk kembali dari hasil kueri dapat meningkatkan kinerja dengan:
Saat menggunakan proyeksi untuk menghapus bidang yang tidak digunakan, server MongoDB harus mengambil setiap dokumen lengkap ke dalam memori (jika belum ada di sana) dan memfilter hasilnya untuk kembali. Penggunaan proyeksi ini tidak mengurangi penggunaan memori atau bekerja pada server MongoDB, tetapi dapat menghemat bandwidth jaringan yang signifikan untuk hasil kueri tergantung pada model data Anda dan bidang yang diproyeksikan.
Permintaan tertutup adalah kasus khusus di mana semua bidang yang diminta dalam hasil permintaan termasuk dalam indeks yang digunakan, sehingga server tidak harus mengambil dokumen lengkap. Kueri yang tercakup dapat meningkatkan kinerja (dengan menghindari mengambil dokumen) dan penggunaan memori (jika permintaan lain tidak mengharuskan mengambil dokumen yang sama).
Contohnya
Untuk tujuan demonstrasi melalui
mongo
shell, bayangkan Anda memiliki dokumen yang terlihat seperti ini:Bidang
b
mungkin mewakili pemilihan nilai (atau dalam hal ini string yang sangat panjang).Selanjutnya, buat indeks
{a:1}
yang merupakan bidang yang biasa digunakan ditanyakan oleh use case Anda:Sederhana
findOne()
tanpa kriteria proyeksi mengembalikan hasil kueri sekitar 10MB:Menambahkan proyeksi
{a:1}
akan membatasi output ke bidanga
dan dokumen_id
(yang disertakan secara default). Server MongoDB masih memanipulasi dokumen 10MB untuk memilih dua bidang, tetapi hasil kueri sekarang hanya 33 byte:Kueri ini tidak tercakup karena dokumen lengkap harus diambil untuk menemukan
_id
nilainya. The_id
bidang termasuk dalam query hasil secara default karena merupakan pengenal unik untuk dokumen, tapi_id
tidak akan dimasukkan dalam indeks sekunder kecuali secara eksplisit menambahkan.The
totalDocsExamined
dantotalKeysExamined
metrik dalamexplain()
hasil akan menunjukkan berapa banyak dokumen dan kunci Indeks diperiksa:Permintaan ini dapat ditingkatkan dengan menggunakan proyeksi untuk mengecualikan
_id
bidang dan mencapai permintaan tertutup hanya menggunakan{a:1}
indeks. Permintaan yang tercakup tidak lagi perlu mengambil dokumen ~ 10MB ke dalam memori, sehingga akan efisien dalam penggunaan jaringan dan memori:Ini tidak dapat dijawab tanpa konteks permintaan tertentu, contoh dokumen, dan penjelasan lengkap hasil. Namun, Anda dapat menjalankan beberapa tolok ukur di lingkungan Anda sendiri untuk kueri yang sama dengan dan tanpa proyeksi untuk membandingkan hasilnya. Jika proyeksi Anda menambahkan overhead signifikan ke keseluruhan waktu pelaksanaan kueri (memproses dan mentransfer hasil), ini mungkin petunjuk kuat bahwa model data Anda dapat ditingkatkan.
Jika tidak jelas mengapa permintaan lambat, sebaiknya mengirim pertanyaan baru dengan detail spesifik untuk diselidiki.
sumber
Dengan proyeksi, Anda dapat mencapai situasi di mana set hasil berasal langsung dari indeks.
Jika Anda memiliki indeks gabungan di
{x:1, y:1, z:1}
mana tidak ada x, y, z adalah _id, Anda perlu memproyeksikan{_id:0, x:1, y:1, z:1}
karena_id
selalu dikembalikan sebagai bagian dari set hasil (ketika tidak diproyeksikan pergi) dan mesin perlu membaca datafile untuk mendapatkannya. Ini karena, indeks tidak memiliki nilai _id, hanya penunjuk ke dokumen tempat nilai disimpan.sumber
_id
respon yang dikembalikan, apakah itu sesuai dengan RAM? Apakah itu membantu?_id:0
maka hasilnya dikembalikan sepenuhnya dari RAM, tanpa membaca data dari disk.