MongoDB встроенный и эталонный с точки зрения производительности - PullRequest
16 голосов
/ 14 июня 2011

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

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

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

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

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

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

Ответы [ 3 ]

12 голосов
/ 14 июня 2011

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                    |
 ---------------------------------------------------------------
3 голосов
/ 15 июня 2011

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

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

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

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

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

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

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

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

О 3. и 4. У меня нет данных для подтверждения.

КСТАТИ 2 коллекции легче кодировать / использовать / управлять.И вы можете просто зарегистрировать blogId в каждом документе 'blog' и добавить "blogId": "1234ABCD" во все ваши запросы

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