Подтвердить что ты не робот

MongoDB встроен против ссылки с точки зрения производительности

Я читал, что внедрение лучше с точки зрения производительности: "Если производительность - это проблема, вставьте". (http://www.mongodb.org/display/DOCS/Schema+Design), и большинство руководств всегда говорят, что вложения должны быть встроены.

Однако я не уверен, что это так. Предположим, у нас есть два объекта: "Блог и почта". Блог содержит сообщения.

Теперь создание всех сообщений, встроенных в блог, будет иметь следующие проблемы:

  • Paging. Поскольку невозможно фильтровать внедренные объекты, мы всегда будем получать все сообщения и должны их отфильтровывать в приложении.
  • Фильтрация. То же, что и раньше, при поиске слов внутри сообщений невозможно будет фильтровать встроенную коллекцию из MongoDB.
  • Вставить. Я предполагаю, что вставка в коллекцию происходит быстрее, чем вставка в внедренный объект. Это верно? это написано где угодно?
  • Обновление. То же, что и раньше, встроенное поле для обновления внутри меньшего документа (Post) может быть быстрее, чем встроенное обновление сообщения внутри большого документа блога. Правильно ли это?

Принимая все вышеизложенное, я бы пошел за публикациями в отдельной коллекции, ссылающейся на блог. Это правильный вывод?

(Примечание. Пожалуйста, не учитывайте ограничение размера документа в ответе, пусть каждый блог будет иметь не более 1000 сообщений)

4b9b3361

Ответ 1

1. Возможно использование $slice:

db.blogs.find({}, {posts:{$slice: [10, 10]}}) // skip 10, limit 10

2. Возможна также фильтрация:

db.blogs.find({"posts.title":"Mongodb!"}, {posts:{$slice: 1}}) //take one post

3,4. Вообще, я думаю, вы говорите о небольшой разнице в производительности. Это не ракетостроение, а просто блог с не более 1000 сообщений.

Ты сказал:

Is this the correct conclusion?

Нет, если вам нужна производительность (в общем случае, если система будет небольшой, вы можете пойти с отдельным документом).

Я сделал небольшой тест производительности в отношении 3,4, вот результаты:

-----------------------------------------------------------------
| Count/Time |  Inserting posts   | Adding to nested collection |
-------------|--------------------------------------------------               
|   1        |   1 ms             |  28 ms                      |
|   1000     |   81 ms            |  590 ms                     |
|   10000    |   759 ms           |  2723 ms                    |
 ---------------------------------------------------------------

Ответ 2

Как и для 3 и 4, если вы вставляете во вложенный документ, это в основном обновление.

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

Если ваше обновление не изменяет размер документа (это означает, что у вас была пара ключей\значение и просто изменилось значение на новое значение, занимающее столько же места), тогда вы будете в порядке, но когда вы начать изменять документы и добавлять новые данные, возникает проблема.

Проблема заключается в том, что в то время как MongoDB выделяет больше места, чем нужно для каждого документа, этого может быть недостаточно. Если вы введете документ размером 1k, MongoDB может предоставить 1.5k для документа, чтобы гарантировать, что незначительные изменения в документе имеют достаточно места для роста. Если вы используете больше, чем выделенное пространство, MongoDB должен извлечь весь документ и переписать его в конец файла.

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

Это, в конечном счете, копируется в память, а это значит, что вы можете использовать 2 ГБ ОЗУ для хранения своего набора данных, в то время как на самом деле сами данные занимают всего 1,5 ГБ, потому что их карман составляет 0,5 ГБ. Эту фрагментацию можно избежать, выполняя вставки, а не обновления. Его также можно устранить, выполнив ремонт базы данных.

В следующей версии MongoDB появится функция онлайн-уплотнения.

Ответ 3

  • Вы можете пейджинговать с '$ срезом на встроенном элементе
  • Вы можете выполнить поиск с помощью "field1.field2":/aRegex/ с aRegex - это слово, которое вы ищете. Но заботиться о производительности.

Около 3. и 4. У меня нет данных о доказательствах.

Коллекции BTW 2 могут быть проще кодировать/использовать/управлять. И вы можете просто зарегистрировать blogId в каждом блоге и добавить "blogId": "1234ABCD" во весь ваш запрос