MongoDB вставка компромиссов скорости - PullRequest
2 голосов
/ 19 августа 2011

Вкратце: Существует огромная разница в скорости вставки, когда я сохраняю объект JSON со многими полями в одном строковом поле MongoDB или оставляю каждое поле объекта JSON в своем собственном MongoDB поле. 1) Это нормальная разница? 2) Эти скорости вставки типичны?

У меня есть много записей, каждая из которых имеет уникальный идентификатор строки и 600 целочисленных значений. Они уже представлены в виде объектов JSON в файле - каждый документ в отдельной строке. Если я представляю документ MongoDB как набор целочисленных полей и помещаю свой уникальный идентификатор в поле _id MongoDB, я могу вставлять около 50 документов в секунду . Если вместо этого я создаю документ только с двумя полями (_id для уникального идентификатора строки и val как единственная строка, в которой хранится вся строка JSON записи), я могу вставить около 100 документов в секунду .

Я использую клиент Python и попытался выполнить пакетную вставку (например, 10, 100, 1000 одновременно). Разница всегда есть. Ожидается ли такое поведение? Я наивно полагал, что не увижу разницы, потому что MongoDB хранит записи как BSON, и не должно быть большой разницы между 600 полями, каждое с целым или единственным строка, содержащая запись JSON, которая, в свою очередь, содержит 600 целых чисел.

Приложение: 1) Я делаю преобразование из JSON в словарь в обоих случаях, чтобы убедиться, что оно не влияет на измерение скорости (т. Е. json.loads и другие вещи). Другими словами, в случае с одним полем с JSON-строкой я делаю все, что делаю в другом случае, но игнорирую преобразованный словарь.

2) Я также пробовал пробный запуск, все в порядке, без вставки в MongoDB. Я могу обрабатывать около 700-800 строк в секунду.

3)

a. db.test.stats() in single-line-single field case (i.e. fast case):
{
    "ns" : "tmp.test",
    "count" : 7999,
    "size" : 71262392,
    "avgObjSize" : 8908.91261407676,
    "storageSize" : 88751616,
    "numExtents" : 9,
    "nindexes" : 1,
    "lastExtentSize" : 21742848,
    "paddingFactor" : 1,
    "flags" : 1,
    "totalIndexSize" : 466944,
    "indexSizes" : {
        "_id_" : 466944
    },
    "ok" : 1
}

b. db.test.stats() (each column to a separate case; i.e., slow case):
{
    "ns" : "tmp.test",
    "count" : 7999,
    "size" : 85710500,
    "avgObjSize" : 10715.15189398675,
    "storageSize" : 107561984,
    "numExtents" : 9,
    "nindexes" : 1,
    "lastExtentSize" : 26091264,
    "paddingFactor" : 1,
    "flags" : 1,
    "totalIndexSize" : 466944,
    "indexSizes" : {
        "_id_" : 466944
    },
    "ok" : 1
}

1 Ответ

3 голосов
/ 19 августа 2011

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

Редактировать: Обратите внимание, что когда я говорю "включить расширения C", я имею в виду пересобрать pymongo или использовать готовый двоичный файл для вашей платформы, в которой собраны модули C. Вы можете увидеть доступные двоичные пакеты на http://pypi.python.org/pypi/pymongo/2.0.1#downloads

...