sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB Regex, Index &Performance

MongoDB stöder reguljära uttryck med $regex-operatorn. Men dessa MongoDB regex-frågor har en nackdel, alla utom en typ av regex använder index dåligt och resulterar i prestandaproblem. För en produktionsserver med stora mängder data kan en dålig regex-fråga få din server på knä.

MongoDB regexbaserade frågor är en ganska vanlig fråga i de flesta applikationer som använder MongoDB. Detta liknar "LIKE"-operationen som stöds i de flesta relationsdatabaser. Syntaxen för kommandot är som följer

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

För mer detaljerad information om regex-operationen och ytterligare alternativ, se MongoDB-dokumentationen

För resten av denna diskussion kommer vi att anta att fältet du matchar mot har ett index. Om du inte indexerar kommer det att resultera i en samlingsskanning och mycket dålig prestanda. Men även om fältet är indexerat kan det resultera i dålig prestanda. Anledningen är att MongoDB bara kan använda index på ett bra sätt om ditt reguljära uttryck är ett "prefixuttryck" – det här är uttryck som börjar med tecknet "^".

T.ex. { namn: { $regex: /^acme/}}

Detta gör att MongoDB kan identifiera ett intervall av de indexposter som är relevanta för denna fråga och resulterar i effektiva frågor. Alla andra frågor resulterar i en indexsökning eftersom MongoDB inte kan begränsa sökningen till ett antal indexposter. En indexskanning är särskilt dålig eftersom alla index måste sökas in i minnet och detta påverkar arbetsuppsättningen på din server (indexskanningen kan faktiskt leda till sämre prestanda än en samlingsskanning - det resulterar i dubbelt så många sidfel ).

Låt oss titta på några exempel och de resulterande frågeplanerna. För våra teständamål har jag skapat en samling med 100 000 dokument. Varje dokument har ett förnamnsfält som är en sträng på 16 tecken.

Exempel 1: { namn:{ $regex:/^acme/}}
Resultat :Effektiv indexanvändning
Frågeplan:

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

Exempel 2: { namn:{ $regex:/^acme/i}}
Resultat:Ineffektiv indexskanning på grund av skiftlägesokänsliga krav. Så i princip förnekar /i-alternativet "prefixuttrycket"
Frågeplan:

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

Exempel 3: { namn:{ $regex:/acme.*corp/}}
Resultat:Ineffektiv indexskanning
Frågeplan:

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

Exempel 4: { namn:{ $regex:/acme/}}
Resultat:Ineffektiv indexskanning

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

  1. MongoDB bästa praxis för referenser

  2. Skickar ytterligare burkar till Spark via spark-submit

  3. Konvertera en sträng till ett tal i MongoDB-projektion

  4. Mongoose &unikt fält