2016-05-05 3 views
5

У меня есть коллекция с большим количеством документов (32 809 900). Все документы имеют поле под названием soft_deleted. Я также создал поле soft_deleted: 1. Затем я проверил несколько разных запросов, связанных с полем. Вот мои результаты:MongoDB запрос по индексированному полю очень медленный

Query        Number of results Time in milliseconds 
db.cgm_egvs 
    .find().count()     32809900   90 
db.cgm_egvs 
    .find({soft_deleted: true})  2820897   688 
    .count() 
db.cgm_egvs 
    .find({soft_deleted: false})  29989003   3983 
    .count() 
db.cgm_egvs 
    .find({soft_deleted: null})  0     42 
    .count() 
db.cgm_egvs 
    .find({soft_deleted: {$ne: true}}) 29989003   82397 
    .count() 

Почему запросы запросов различаются между этими запросами? Я ожидаю найти документы, где soft_deleted - true или false, чтобы взять такое же количество времени. Что еще более важно, почему запрос != true настолько медленнее, чем любой другой запрос?

+1

Вы могли бы добавить **. Объяснить («executeStats») ** в конце каждого результата объявления объявления. Это позволит получить больше деталей выполнения. – profesor79

+0

Истинное противоречие с ложью может быть объяснено селективностью индекса. Например, если 10% ваших документов имеют soft_deleted: true, индекс полезен для соответствия soft_deleted: true. С другой стороны, при поиске soft_deleted: false, индекс бесполезен. – joao

ответ

3

soft_deleted поле имеет очень низкую мощность; он имеет только два разных значения true и false, поэтому вам не будет иметь большого преимущества с индексом в этом поле. Обычно индексы лучше работают на полях с высокой мощностью.

В случае запроса {soft_deleted: true} количество строк с soft_deleted: true очень мало по сравнению с {soft_deleted: false}, а mongodb пришлось сканировать гораздо меньшее количество записей индекса. Поэтому запрос {soft_deleted: true} занял меньше времени.

Аналогично, запрос {soft_deleted: null} занял меньше времени, так как индекс имеет только 2 различных значения, и в этом случае требуется гораздо меньшее сканирование.

Ваш последний запрос использует оператор $ ne, а оператор $ ne не является выборочным (селективность - это возможность запроса для узких результатов с использованием индекса). https://docs.mongodb.com/v3.0/faq/indexes/#using-ne-and-nin-in-a-query-is-slow-why. Так что потребовалось гораздо больше времени для выполнения.

0

Я не уверен, почему другие запросы медленны (поскольку я ожидаю объяснения дампа), , но в случае $ ne точка в том, что у нас есть дополнительный шаг, добавленный туда, так что эта функция будет обернута в первом равном и то не равно -> см объяснить дамп ниже в parsedQuery раздела и найти не шаг

db.getCollection ('a1') найти ({Уровень: {$ пе: "Info"}}). .explain()

"queryPlanner" : { 
    "plannerVersion" : 1, 
    "namespace" : "logi.a1", 
    "indexFilterSet" : false, 
    "parsedQuery" : { 
     "$not" : { 
      "Level" : { 
       "$eq" : "Info" 
      } 
     } 
    }, 
.. 210

db.getCollection ('a1') найти ({Уровень: "Info"}) объяснить()

"queryPlanner" : { 
    "plannerVersion" : 1, 
    "namespace" : "logi.a1", 
    "indexFilterSet" : false, 
    "parsedQuery" : { 
     "Level" : { 
      "$eq" : "Info" 
     } 
    }, 
Смежные вопросы