0

фонMongoDB MultiKey индекс Perfomance

У меня есть коллекция пользователей со структурой документов, как это:

{ 
    "_id" : ObjectId("54e61137cca5d2ff0a8b4567"), 
    "login" : "test1", 
    "emails" : [ 
     { 
      "email" : "[email protected]", 
      "is_primary" : true, 
      "_id" : ObjectId("57baf3e97323afb2688e639c") 
     }, 
     { 
      "email" : "[email protected]", 
      "is_primary" : false, 
      "_id" : ObjectId("57baf3e97323afb2688e639d") 
     } 
    ] 
} 

Индексы:

{ 
    "v" : 1, 
    "key" : { 
     "login" : 1 
    }, 
    "name" : "login_1", 
    "ns" : "mydb.users", 
    "background" : true 
}, 
{ 
    "v" : 1, 
    "key" : { 
     "emails.email" : 1 
    }, 
    "name" : "emails.email_1", 
    "ns" : "mydb.users" 
} 

Количество документов ~ 700000

Сценарий

Для объяснения поиска пользователей по логину, я делаю это:

rs0:PRIMARY> db.users.explain('executionStats').find({'login' : /test123123123/}) 
{ 
    "queryPlanner" : { 
     "plannerVersion" : 1, 
     "namespace" : "mydb.users", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "login" : /test123123123/ 
     }, 
     "winningPlan" : { 
      "stage" : "FETCH", 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "filter" : { 
        "login" : /test123123123/ 
       }, 
       "keyPattern" : { 
        "login" : 1 
       }, 
       "indexName" : "login_1", 
       "isMultiKey" : false, 
       "direction" : "forward", 
       "indexBounds" : { 
        "login" : [ 
         "[\"\", {})", 
         "[/test123123123/, /test123123123/]" 
        ] 
       } 
      } 
     }, 
     "rejectedPlans" : [ ] 
    }, 
    "executionStats" : { 
     "executionSuccess" : true, 
     "nReturned" : 0, 
     "executionTimeMillis" : 1040, 
     "totalKeysExamined" : 698993, 
     "totalDocsExamined" : 0, 
     "executionStages" : { 
      "stage" : "FETCH", 
      "nReturned" : 0, 
      "executionTimeMillisEstimate" : 930, 
      "works" : 698994, 
      "advanced" : 0, 
      "needTime" : 698993, 
      "needFetch" : 0, 
      "saveState" : 5460, 
      "restoreState" : 5460, 
      "isEOF" : 1, 
      "invalidates" : 0, 
      "docsExamined" : 0, 
      "alreadyHasObj" : 0, 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "filter" : { 
        "login" : /test123123123/ 
       }, 
       "nReturned" : 0, 
       "executionTimeMillisEstimate" : 920, 
       "works" : 698993, 
       "advanced" : 0, 
       "needTime" : 698993, 
       "needFetch" : 0, 
       "saveState" : 5460, 
       "restoreState" : 5460, 
       "isEOF" : 1, 
       "invalidates" : 0, 
       "keyPattern" : { 
        "login" : 1 
       }, 
       "indexName" : "login_1", 
       "isMultiKey" : false, 
       "direction" : "forward", 
       "indexBounds" : { 
        "login" : [ 
         "[\"\", {})", 
         "[/test123123123/, /test123123123/]" 
        ] 
       }, 
       "keysExamined" : 698993, 
       "dupsTested" : 0, 
       "dupsDropped" : 0, 
       "seenInvalidated" : 0, 
       "matchTested" : 0 
      } 
     } 
    }, 
    "serverInfo" : { 
     "host" : "myhost", 
     "port" : 27017, 
     "version" : "3.0.12", 
     "gitVersion" : "33934938e0e95d534cebbaff656cde916b9c3573" 
    }, 
    "ok" : 1 
} 

Как вы можете видеть executionStats.executionStages.inputStage.nReturned является 0 и executionStats.totalDocsExamined так 0. Это нормально , Я думаю, что нет документов с логином, например, введенным. Но если я хочу искать пользователей по электронной почте я буду делать дальше:

rs0:PRIMARY> db.users.explain('executionStats').find({'emails.email' : /test123123123/}) 
{ 
    "queryPlanner" : { 
     "plannerVersion" : 1, 
     "namespace" : "mydb.users", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "emails.email" : /test123123123/ 
     }, 
     "winningPlan" : { 
      "stage" : "FETCH", 
      "filter" : { 
       "emails.email" : /test123123123/ 
      }, 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "keyPattern" : { 
        "emails.email" : 1 
       }, 
       "indexName" : "emails.email_1", 
       "isMultiKey" : true, 
       "direction" : "forward", 
       "indexBounds" : { 
        "emails.email" : [ 
         "[\"\", {})", 
         "[/test123123123/, /test123123123/]" 
        ] 
       } 
      } 
     }, 
     "rejectedPlans" : [ ] 
    }, 
    "executionStats" : { 
     "executionSuccess" : true, 
     "nReturned" : 0, 
     "executionTimeMillis" : 7666, 
     "totalKeysExamined" : 699016, 
     "totalDocsExamined" : 698993, 
     "executionStages" : { 
      "stage" : "FETCH", 
      "filter" : { 
       "emails.email" : /test123123123/ 
      }, 
      "nReturned" : 0, 
      "executionTimeMillisEstimate" : 7355, 
      "works" : 699017, 
      "advanced" : 0, 
      "needTime" : 699016, 
      "needFetch" : 0, 
      "saveState" : 5462, 
      "restoreState" : 5462, 
      "isEOF" : 1, 
      "invalidates" : 0, 
      "docsExamined" : 698993, 
      "alreadyHasObj" : 0, 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "nReturned" : 698993, 
       "executionTimeMillisEstimate" : 1630, 
       "works" : 699016, 
       "advanced" : 698993, 
       "needTime" : 23, 
       "needFetch" : 0, 
       "saveState" : 5462, 
       "restoreState" : 5462, 
       "isEOF" : 1, 
       "invalidates" : 0, 
       "keyPattern" : { 
        "emails.email" : 1 
       }, 
       "indexName" : "emails.email_1", 
       "isMultiKey" : true, 
       "direction" : "forward", 
       "indexBounds" : { 
        "emails.email" : [ 
         "[\"\", {})", 
         "[/test123123123/, /test123123123/]" 
        ] 
       }, 
       "keysExamined" : 699016, 
       "dupsTested" : 699016, 
       "dupsDropped" : 23, 
       "seenInvalidated" : 0, 
       "matchTested" : 0 
      } 
     } 
    }, 
    "serverInfo" : { 
     "host" : "myhost", 
     "port" : 27017, 
     "version" : "3.0.12", 
     "gitVersion" : "33934938e0e95d534cebbaff656cde916b9c3573" 
    }, 
    "ok" : 1 
} 

И здесь executionStats.executionStages.inputStage.nReturned (и executionStats.totalDocsExamined) равна 698993 (executionStats.nReturned является 0, как и в первом запросе)

Вопрос

Почему, когда я использую поиск с MultiKey индексом (users.user) на IXSCAN этапе возвращает всю свою коллекцию и принеси этапе происходит всю коллекцию. Но если я использую поиск по не-multikey index (login), то ixscan stage сканирует ожидаемые значения, а на этапе выборки я даю то, что хочу.

UPD: когда я использую регулярное выражение не как/smth /, но/^ smth/then scan by email.email field возвращает также 0 элементов. Почему multikey и обычный индекс дают мне разные результаты для регулярного выражения, например/smth /?

ответ

0

Потому что это многокитайский указатель. explained here

Когда фильтр запроса определяет точное совпадение массива в целом, MongoDB может использовать MultiKey индекс для поиска первого элемента массива запросов, но не может использовать MultiKey индексного сканирования, чтобы найти все массив. Вместо этого, после использования индекса multikey для поиска первого элемента массива запросов, MongoDB извлекает связанные документы и фильтры для документов, массив которых соответствует массиву в запросе.

Смежные вопросы