MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Regex MongoDB, Indeks &Kinerja

MongoDB mendukung ekspresi reguler menggunakan operator $regex. Namun, kueri regex MongoDB ini memiliki kelemahan, semua kecuali satu jenis regex menggunakan indeks dengan buruk dan mengakibatkan masalah kinerja. Untuk server produksi dengan data dalam jumlah besar, kueri regex yang buruk dapat membuat server Anda bertekuk lutut.

Kueri berbasis regex MongoDB adalah kueri yang cukup umum di sebagian besar aplikasi yang menggunakan MongoDB. Ini mirip dengan operasi 'LIKE' yang didukung pada sebagian besar database relasional. Sintaks perintahnya adalah sebagai berikut

{ $regex: /pattern/, $options: '<options>' }
E.g. { name: { $regex: /^acme.*test/}}

Untuk informasi lebih rinci tentang operasi regex dan opsi tambahan, lihat dokumentasi MongoDB

Untuk sisa diskusi ini, kami akan menganggap bahwa bidang yang Anda cocokkan memiliki indeks. Jika Anda tidak mengindeksnya, itu akan menghasilkan pemindaian koleksi dan kinerja yang sangat buruk. Namun, bahkan jika bidang diindeks dapat menghasilkan kinerja yang buruk. Alasannya adalah bahwa MongoDB dapat menggunakan indeks dengan baik hanya jika ekspresi reguler Anda adalah "ekspresi awalan" – ini adalah ekspresi yang dimulai dengan karakter "^".

Misalnya. { name: { $regex: /^acme/}}

Ini memungkinkan MongoDB untuk mengidentifikasi rentang entri indeks yang relevan dengan kueri ini dan menghasilkan kueri yang efisien. Permintaan lainnya menghasilkan pemindaian indeks karena MongoDB tidak dapat mempersempit pemindaian ke kisaran entri indeks. Pemindaian indeks sangat buruk karena semua indeks perlu dimasukkan ke dalam memori dan ini memengaruhi set kerja server Anda (Bahkan pemindaian indeks dapat menyebabkan kinerja yang lebih buruk daripada pemindaian koleksi – ini menghasilkan dua kali jumlah kesalahan halaman ).

Mari kita lihat beberapa contoh dan rencana kueri yang dihasilkan. Untuk tujuan pengujian kami, saya telah menyiapkan koleksi dengan 100 ribu dokumen. Setiap dokumen memiliki field FirstName yang merupakan string 16 karakter.

Contoh 1: { nama:{ $regex:/^acme/}}
Hasil :Penggunaan indeks yang efisien
Rencana kueri:

executionStats" : {
       "executionSuccess" : true,
       "nReturned" : 0,
       "executionTimeMillis" : 0,
       "totalKeysExamined" : 1,
       "totalDocsExamined" : 0,

Contoh 2: { name:{ $regex:/^acme/i}}
Hasil :Pemindaian indeks tidak efisien karena persyaratan tidak peka huruf besar/kecil. Jadi pada dasarnya opsi /i meniadakan "ekspresi awalan"
Paket kueri:

        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 137,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

Contoh 3: { name:{ $regex:/acme.*corp/}}
Hasil :Pemindaian indeks tidak efisien
Rencana kueri:

                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 167,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

Contoh 4: { name:{ $regex:/acme/}}
Hasil :Pemindaian indeks tidak efisien

        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 130,
                "totalKeysExamined" : 100000,
                "totalDocsExamined" : 0,

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cara Mendapatkan Hari, Bulan, dan Tahun dari Tanggal di SQL

  2. populasi rekursif luwak

  3. $sum bersyarat di MongoDB

  4. mongodb:menemukan nilai numerik tertinggi dari sebuah kolom

  5. Temukan Nilai yang Tidak Mengandung Angka dalam SQL