Запросы к подчиненному объекту в MongoDB не используют индекс - PullRequest
0 голосов
/ 06 февраля 2011

Я записываю события использования сайта в подобъекте (посетителя).Вот базовый пример структуры данных:

{ "_id" : ObjectId("4d4c695794b332a0740009bd"), "evs" : [
    {
            "ev" : "Visit Home Page",
            "d" : 1,
            "s" : 1
    },
    {
            "ev" : "Buy Product",
            "d" : "110.10",
            "upc" : 1234,
            "s" : 1
    },
    {
            "ev" : "Sign up to newsletter",
            "d" : "1",
            "s" : 1
    }
]}

У меня есть индекс для evs.s, но при поиске по evs.s индекс не используется:

db.visitors.find({'evs.s':0}).explain()
{
    "cursor" : "BtreeCursor evs.s_1",
    "nscanned" : 33361,
    "nscannedObjects" : 33361,
    "n" : 33361,
    "millis" : 311,
    "nYields" : 105,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
            "evs.s" : [
                    [
                            0,
                            0
                    ]
            ]
    }
}

Этот запрос занимает 311 миллисекунд и просматривает каждый объект.

Вот индекс: db.visitors.getIndexes ()

{
  "ns" : "tracking.visitors",
  "unique" : false,
  "key" : {
     "evs.s" : 1
  },
  "name" : "evs.s_1",
  "v" : 0
}

Ответы [ 2 ]

2 голосов
/ 06 февраля 2011

Ваш запрос фактически использует индекс, как указано типом курсора в выводе объяснения ("BtreeCursor evs.s_1"). Если вы не используете индекс, это будет «BasicCursor».

Судя по вашим входным данным, evs.s может быть не очень эффективным ключом для индексации. Если все значения evs.s равны 1 или 0, ваш индекс всегда будет совпадать с большим количеством совпадений.

Я предполагаю, что ваш запрос не выполнял полное сканирование таблицы, но на самом деле в вашем индексе так много записей со значением evs.s = 0.

Вы можете сравнить вывод

db.visits.find ({evs.s: 0}). Count ();

db.visits.find ({evs.s: 1}). Count ();

db.visits.find () рассчитывать ();.

, чтобы проверить это.

Есть несколько способов ускорить процесс:

1) Вы можете использовать другой индекс, который имеет более четкие значения. Это уменьшит пространство поиска для каждого запроса.

2) Вы можете добавить предельный оператор к вашему запросу. Это прекратит сканирование индекса после того, как будут найдены предельные документы.

0 голосов
/ 06 февраля 2011

«курсор»: «BtreeCursor evs.s_1»

означает, что используется индекс .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...