Как улучшить производительность запросов с такими операторами, как $ nin, $ in для Mongodb - PullRequest
1 голос
/ 19 мая 2011

У меня достаточно большой набор данных из более чем 3 миллионов документов, теги которых похожи на StackOverflow, который использует теги для каждого вопроса.Схема, которую я использую для хранения тегов, выглядит следующим образом:

{"id": 12345, "tags":["tag1", "tag2", "tag3"]}, {"id": 12346, "tags":["tag2", "tag3"]}

У меня есть многоключевой индекс, созданный для поля тегов.Когда я выполняю запросы с использованием операторов $ in или $ nin, чтобы найти пересечение, объединение тегов, на компьютере серверного класса производительность составляет около 7 секунд.Могу ли я что-нибудь сделать, чтобы улучшить скорость поиска по запросу?

РЕДАКТИРОВАТЬ 1:

Вот план объяснения по запросу.Я заметил, что запросы возвращались намного быстрее после того, как я перезапустил свой сервер и просто запустил только сервер mongodb.Запросы выполняются намного быстрее (<50 мс).Я подозреваю, что индексы не кэшировались в памяти, хотя у меня было достаточно свободного неиспользуемого ОЗУ, и мой индекс (800 МБ) мог легко поместиться в памяти. </p>

db.tagsCollection.find ({"tags": {$ in: ['tag1', 'tag2'], $ nin: ['tag4', 'tag5', 'tag6', 'tag7']}}) .explain ();{"cursor": "BtreeCursor tags_1 multi", "nscanned": 6145193, "nscannedObjects": 6145192, "n": 969386, "millis": 19640, "nYields": 0, "nChunkSkips": 0, "isMultiKey": true, "indexOnly": false, "indexBounds": {"tags": [["tag1", "tag1"], ["tag2", "tag2"]]}}

Примечание

Ответы [ 4 ]

4 голосов
/ 19 мая 2011

Это то, что я считал оптимизацией (хотя вам, возможно, понадобится проверить это)

  1. Вместо хранения тегов сохраните небольшой ключ, который идентифицирует все теги, которые имеет конкретный документ. скажем, для поста № 125 есть следующие теги: PHP, MongoDb, база данных.

    а) очистить теги, например, преобразовать их в небольшой регистр и т. Д. а затем сортировать их по алфавиту. текущие теги будут: база данных, mongodb, php

    б) иметь отдельную коллекцию, в которой хранится целочисленное отображение тегов:

    {"_id": 1, "t": "mongodb"}

    {"_id": 2, "t": "php"} и т. Д. Сохраните все возможные теги для вашего сайта

    в) для сохранения документа создайте ключ тега, используя теги для нумерации из предыдущей коллекции. таким образом, текущая база данных, mongodb, php станет чем-то вроде 1-12-2

    d) сохранить ваш документ как:

    {"id": 12345, "tags": [1,12,3]}

ЗАПРОС: Использование целых чисел вместо строк в индексированном поле значительно уменьшит размер индекса, а также ускорит выполнение запросов по сравнению со строковым индексом. Не уверен насчет увеличения производительности, но все же стоит попробовать сравнить с текущей реализацией.

1 голос
/ 19 мая 2011

Проверьте размер индекса мультиключевых тегов, используя db.col.stats().Если он не помещается в ОЗУ, возможно, вы привязаны к диску и понесете некоторую стоимость дискового ввода-вывода.Если индекс полностью умещается в памяти, то я не уверен, что еще вы можете сделать, кроме как бросить на него больше оборудования, если только вы не можете оптимизировать сами запросы.Или вы можете запросить подмножество, отфильтрованное другим индексированным полем?Или вы можете исключить запросы $nin, которые, как правило, будут выполняться медленнее, потому что приходится повторять каждый тег, где только $ in должен повторять, пока не найдет совпадение.

0 голосов
/ 22 апреля 2014

Вот еще одно предложение, но у меня не было возможности проверить его.

{ 
    tags:{ 
        items:[ 'a', 'b', 'c' ],
        mixed:{
            a:1, // hash value for a tag
            b:2, // hash value for b tag
            c:3  // hash value for c tag
        }
    }
}

и поисковый запрос

db.demo.find({ 'tags.mixed.a':1, 'tags.mixed.b':2  })

если возможно, необходимо создать составной индекс для tags.mixed

0 голосов
/ 21 августа 2012

Если вы хотите, чтобы производительность была очень быстрой и не имели пробелов, я бы посоветовал иметь отдельную коллекцию тегов с массивом идентификаторов видео и иметь индекс по имени тега.

...