Pengindeksan luwak dalam kode produksi

124

Sesuai dokumentasi Mongoose untuk MongooseJSdan MongoDB/ Node.js:

Saat aplikasi Anda dimulai, Mongoose secara otomatis memanggil ensureIndexsetiap indeks yang ditentukan dalam skema Anda. Meskipun bagus untuk pengembangan, disarankan agar perilaku ini dinonaktifkan dalam produksi karena pembuatan indeks dapat menyebabkan dampak kinerja yang signifikan. Nonaktifkan perilaku tersebut dengan menyetel autoIndexopsi skema Anda ke false.

Ini tampaknya menginstruksikan penghapusan pengindeksan otomatis dari luwak sebelum menerapkan untuk mengoptimalkan Mongoose dari menginstruksikan Mongo untuk pergi dan melakukan churn melalui semua indeks saat memulai aplikasi, yang tampaknya masuk akal.

Apa cara yang tepat untuk menangani pengindeksan dalam kode produksi? Mungkin skrip eksternal harus menghasilkan indeks? Atau mungkin ensureIndextidak diperlukan jika satu aplikasi adalah satu-satunya pembaca / penulis untuk sebuah koleksi karena itu akan melanjutkan indeks setiap kali terjadi penulisan DB?

Sunting: Untuk melengkapi, MongoDB menyediakan dokumentasi yang baik tentang bagaimana melakukan pengindeksan, tetapi tidak mengapa atau kapan arahan pengindeksan eksplisit harus dilakukan. Menurut saya indeks harus tetap diperbarui oleh aplikasi penulis secara otomatis pada koleksi dengan indeks yang ada dan itu ensureIndexbenar-benar lebih dari satu kali (dilakukan ketika indeks baru diterapkan), dalam hal ini Mongoose autoIndexharus menjadi no-op di bawah restart server normal.

Nick S.
sumber

Jawaban:

135

Saya tidak pernah mengerti mengapa dokumentasi Mongoose secara luas merekomendasikan penonaktifan autoIndexdalam produksi. Setelah indeks ditambahkan, ensureIndexpanggilan berikutnya hanya akan melihat bahwa indeks sudah ada dan kemudian kembali. Jadi ini hanya berpengaruh pada kinerja saat Anda pertama kali membuat indeks, dan pada saat itu koleksinya sering kali kosong sehingga membuat indeks akan cepat.

Saran saya adalah membiarkannya autoIndexdiaktifkan kecuali Anda memiliki situasi tertentu yang membuat Anda kesulitan; seperti jika Anda ingin menambahkan indeks baru ke koleksi yang sudah ada yang memiliki jutaan dokumen dan Anda ingin lebih mengontrol saat dibuat.

JohnnyHK
sumber
10
Saya punya pertanyaan untuk ditambahkan ... Bagaimana jika saya menyetelnya sebagai false? Daripada indeks akan dibuat ketika saya memasukkan data atau apakah saya perlu membuatnya secara eksplisit. Saya minta maaf jika ini adalah pertanyaan pemula tetapi akan sangat membantu jika Anda menjawab.
Saransh Mohapatra
5
@SaranshMohapatra Jika autoIndexsalah, Anda perlu memanggil sureIndexes pada model Anda untuk membuat indeksnya.
JohnnyHK
Lalu apakah saya harus menyebutnya setiap kali atau hanya sekali menentukan model?
Saransh Mohapatra
@SaranshMohapatra saat Anda mendefinisikan (mengompilasi) model Anda. Saya melakukannya saat pertama kali memulai aplikasi. Sekarang yang sulit dipikirkan adalah memutuskan untuk menghapus semua indeks dan membuatnya kembali, jika skema Anda berubah.
Moss
3
@JohnnyHK apakah Anda masih setuju dengan jawaban Anda sekarang karena sudah hampir 2016?
Alexander Mills
41

Meskipun saya setuju dengan jawaban yang diterima, perlu dicatat bahwa menurut manual MongoDB , ini bukan cara yang disarankan untuk menambahkan indeks pada server produksi:

Jika aplikasi Anda menyertakan operasi sureIndex (), dan indeks tidak ada untuk masalah operasional lainnya, membangun indeks dapat berdampak parah pada kinerja database.

Untuk menghindari masalah kinerja, pastikan bahwa aplikasi Anda memeriksa indeks saat memulai menggunakan metode getIndexes () atau metode yang setara untuk driver Anda dan menghentikan jika indeks yang tepat tidak ada. Selalu buat indeks dalam contoh produksi menggunakan kode aplikasi terpisah, selama masa pemeliharaan yang ditentukan.

Tentu saja, ini sangat bergantung pada bagaimana aplikasi Anda disusun dan diterapkan. Jika Anda menerapkan ke Heroku, misalnya, dan Anda tidak menggunakan fitur pra - booting Heroku , kemungkinan aplikasi Anda tidak melayani permintaan sama sekali selama permulaan, jadi mungkin aman untuk membuat indeks pada saat itu.

Selain itu, dari jawaban yang diterima:

Jadi ini hanya berpengaruh pada kinerja saat Anda pertama kali membuat indeks, dan pada saat itu koleksinya sering kali kosong sehingga membuat indeks akan cepat.

Jika Anda telah berhasil mendapatkan model data dan kueri Anda untuk pertama kalinya, ini bagus, dan seringkali demikian. Namun, jika Anda menambahkan fungsionalitas baru ke aplikasi Anda, dengan kueri DB baru pada properti tanpa indeks, Anda akan sering menemukan diri Anda menambahkan indeks ke koleksi yang berisi banyak dokumen yang sudah ada.

Ini adalah waktu di mana Anda perlu berhati-hati dalam menambahkan indeks, dan dengan cermat mempertimbangkan implikasi kinerja dari melakukannya. Misalnya, Anda dapat membuat indeks di latar belakang :

db.ensureIndex({ name: 1 }, { background: true });
Tom Spencer
sumber
3
Oke, jadi yang harus Anda lakukan adalah TIDAK memulai server Anda sampai semua callback sureIndex telah diaktifkan untuk setiap koleksi.
Alexander Mills
@AlexMills bagaimana Anda memastikan itu?
lonelymo
async.each (Object.keys (model), fungsi (key, cb) {models [key] .ensureIndexes (cb)}, cb)
Alexander Mills
cukup panggil sureIndexes pada setiap model luwak, tunggu sampai semua selesai, lalu mulai server Anda; Saya juga merekomendasikan menunggu koneksi db terjadi sebelum memulai server Anda juga
Alexander Mills
2
Tidak ada ensureIndexlagi. Ada createIndexsebagai gantinya. Apakah saya benar?
jack blank
1

gunakan kode blok ini untuk menangani mode produksi:

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });
Masih Jahangiri
sumber