sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB Regex, Index &Performance

MongoDB understøtter regulære udtryk ved hjælp af $regex-operatoren. Men disse MongoDB regex-forespørgsler har en ulempe, alle undtagen én type regex gør dårlig brug af indekser og resulterer i ydeevneproblemer. For en produktionsserver med store mængder data kan en dårlig regex-forespørgsel bringe din server i knæ.

MongoDB regex-baserede forespørgsler er en ret almindelig forespørgsel i de fleste applikationer, der bruger MongoDB. Dette svarer til 'LIKE'-operationen, der understøttes på de fleste relationelle databaser. Syntaksen for kommandoen er som følger

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

For mere detaljeret information om regex-operationen og yderligere muligheder henvises til MongoDB-dokumentationen

I resten af ​​denne diskussion vil vi antage, at feltet du matcher mod har et indeks. Hvis du ikke indekserer, vil det resultere i en indsamlingsscanning og meget dårlig ydeevne. Men selvom feltet er indekseret, kan det resultere i dårlig ydeevne. Årsagen er, at MongoDB kun kan gøre god brug af indekser, hvis dit regulære udtryk er et "præfiksudtryk" - det er udtryk, der starter med tegnet "^".

For eksempel. { navn: { $regex: /^acme/}}

Dette giver MongoDB mulighed for at identificere en række af de indeksposter, der er relevante for denne forespørgsel, og resulterer i effektive forespørgsler. Enhver anden forespørgsel resulterer i en indeksscanning, da MongoDB ikke er i stand til at indsnævre scanningen til en række indeksposter. En indeksscanning er særlig dårlig, da alle indekserne skal indlæses i hukommelsen, og dette påvirker arbejdssættet på din server (faktisk kan indeksscanningen føre til dårligere ydeevne end en samlingsscanning - det resulterer i dobbelt så mange sidefejl ).

Lad os se på nogle eksempler og de resulterende forespørgselsplaner. Til vores testformål har jeg opsat en samling med 100.000 dokumenter. Hvert dokument har et fornavn-felt, som er en streng på 16 tegn.

Eksempel 1: { navn:{ $regex:/^acme/}}
Resultat :Effektiv indeksbrug
Forespørgselsplan:

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

Eksempel 2: { navn:{ $regex:/^acme/i}}
Resultat:Ineffektiv indeksscanning på grund af krav om ufølsomme store og små bogstaver. Så grundlæggende negerer /i-indstillingen "præfiksudtrykket"
Forespørgselsplan:

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

Eksempel 3: { navn:{ $regex:/acme.*corp/}}
Resultat :Ineffektiv indeksscanning
Forespørgselsplan:

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

Eksempel 4: { navn:{ $regex:/acme/}}
Resultat:Ineffektiv indeksscanning

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

  1. MongoDB - Argumentet til $size skal være et array, men var af typen:EOO / mangler

  2. Redis Stack Exchange hvordan man sletter eller får nøgler efter mønster

  3. MongoDB-projektion af indlejrede arrays

  4. show dbs giver ikke autoriseret til at udføre kommandofejl