MongoDB ограничивает количество разреженных индексов

У меня есть особая потребность иметь особенно большое количество разреженных индексов в коллекции MongoDB. Вероятно, это число будет исчисляться несколькими тысячами. Каждый сохраненный документ будет использовать относительно небольшое количество индексов, в среднем около 10–30 на каждый. Однако документы очень разнообразны, и для каждого из них потребуются разные наборы указателей.

Я не могу найти документацию о возможных последствиях наличия > 1000 разреженных индексов в коллекции. Космос не беспокоит. Меня особенно беспокоит влияние на экономию времени и настройку запросов. Не увязнет ли MongoDB в таких больших накладных расходах?

Я проведу свои собственные тесты, но я хотел бы знать: а) знает ли кто-нибудь какие-либо официальные рекомендации по этому поводу и б) есть ли у него опыт работы с этим сценарием.


person IamIC    schedule 07.07.2012    source источник


Ответы (2)


Существует ограничение пространства имен (общее количество индексов, коллекций и т. д.), с которым вы можете столкнуться, но которое можно снять с помощью --nssize: http://www.mongodb.org/display/DOCS./Использование+a+Больших+Число+коллекций+коллекций

К вставкам будут добавлены некоторые накладные расходы, но они должны «быстро выйти из строя», как только поймут, что вставляемый документ не нужно добавлять в большинство индексов. Отказ от ответственности: я не пробовал проводить бенчмаркинг почти так много, как вы думаете. Мне интересно посмотреть, будет ли это работать.

Следует иметь в виду, что вы не сможете использовать более одного индекса для каждого запроса без использования $or, что является текущим ограничением в mongodb. http://www.mongodb.org/display/DOCS/Indexing+Advice+and+FAQ#IndexingAdviceandFAQ-Oneindexperquery.

person Eve Freeman    schedule 07.07.2012
comment
Вы имеете в виду, что нет возможности одновременно искать несколько частично проиндексированных полей? - person IamIC; 07.07.2012
comment
Ну, вы можете, используя $or -- как будут выглядеть ваши шаблоны запросов? - person Eve Freeman; 07.07.2012
comment
Кроме того, вы можете искать более одного индекса, но он выберет один индекс для использования и просканирует остальные (что, очевидно, нежелательно, если вы ищете быстрые результаты). - person Eve Freeman; 07.07.2012
comment
Спасибо, прочитал ссылку. Странно то, что я протестировал это на запросе с 8 полями, и скорость убила PostgreSQL и SQL Server. Тем не менее, как вы сказали, запрос может использовать только один индекс за раз. - person IamIC; 07.07.2012
comment
Чтобы лучше всего проиллюстрировать то, что я хочу, нарисуйте изображение, хранящее данные о различных типах транспортных средств (автомобили, мотоциклы, грузовики) в коллекции с разреженным индексом, определенным для каждого параметра каждого типа транспортного средства. Тогда запрос может выглядеть примерно так: дайте мне все документы, в которых количество цилиндров находится в диапазоне от 5 до 7, или значение null И цена составляет ‹ 20 000, И мощность двигателя находится в диапазоне от 2000 до 2500, или значение null И вес находится в диапазоне от 1500 до 2000, или значение null. - person IamIC; 07.07.2012
comment
Не удивлен, что он все еще быстрее, чем другие. Mongo действительно хорошо справляется со сканированием коллекции/сканированием индекса, если они помещаются в ОЗУ. Убедитесь, что вы проводите сравнение с объемом данных производственного уровня, чтобы установить реалистичные ожидания. - person Eve Freeman; 07.07.2012
comment
Да, по моему опыту, запросы с несколькими диапазонами являются слабым местом в монго (даже с индексами для всех полей в диапазонах). Вы можете проголосовать за эту (пока незапланированную) проблему, которая, вероятно, улучшит производительность для вашего варианта использования. jira.mongodb.org/browse/SERVER-785 - person Eve Freeman; 07.07.2012
comment
SERVER-785 предназначен для частичных индексов (тоже полезно), но это не то, что мне нужно. - person IamIC; 07.07.2012
comment
Вы можете определить разреженный индекс с несколькими ключами, отфильтровав несуществующие значения — по крайней мере, я так понимаю. Таким образом, вы можете проиндексировать цилиндры, цену, мощность двигателя, вес, но если этих значений не существует, документ не будет проиндексирован. Конечно, вам, возможно, придется создать несколько таких индексов для соответствия вашим запросам, но это была просто идея (и пока не вариант). - person Eve Freeman; 07.07.2012
comment
Я думал, что разреженные индексы позволяют использовать только один ключ (поле) за раз? Моя идея состояла в том, чтобы добавить один индекс для каждого поля. - person IamIC; 08.07.2012
comment
Пс. взаимозаменяемы ли термины «ключ» и «поле» на языке MongoDB? - person IamIC; 08.07.2012
comment
Верно (разреженные индексы предназначены только для одного поля), но эта проблема позволит вам эффективно создавать индексы для более чем одного поля, разреженно (частично). Что касается ключа и поля, я думаю, что они взаимозаменяемы во многих контекстах, но, на мой взгляд, поле — это пара ключ/значение, где ключ — это просто ключ. - person Eve Freeman; 08.07.2012
comment
AFAIK, частичный индекс, технически, представляет собой индекс в предопределенном диапазоне, который не то же самое, что разреженный. - person IamIC; 08.07.2012
comment
Разреженный индекс — это частный случай частичного индекса, поскольку он выходит за пределы диапазона документов, в которых есть значения. - person Eve Freeman; 08.07.2012
comment
Ну, я понимаю, что вы имеете в виду, но технически частичный индекс требует, чтобы фильтр был частичным (en.wikipedia. org/wiki/Partial_index). MongoDB уникален тем, что у него нет схемы, поэтому можно утверждать, что в таком случае ваше утверждение верно :) - person IamIC; 08.07.2012

Пока это не будет реализовано на сервере, вы можете запустить запрос ИЛИ дважды — по одному разу для каждого поля и объединить результаты в клиенте.

Например, если у вас есть объекты:

{_id: 123, foo: 12}
{_id: 124, bar: 13}
{_id: 124, foo: 12, bar: 15}

У вас может быть один разреженный индекс {foo:1, _id:1} и другой {bar:1, _id:1} и выполнять запросы, такие как find({foo:12}, {_id:1}) и find({bar:13}, {_id:1}), а затем ИЛИ или И идентификаторы объектов в клиенте. Затем вы можете получить полные объекты только для тех совпадающих идентификаторов.

Примечание: получая только поле _id в запросах на поиск, Mongo может возвращать результаты из индекса и не нужно распаковывать BSON, чтобы получить результаты, что делает это очень быстрым.

person Nic Cottrell    schedule 21.01.2013