Извлечение производительности многих строк из CouchDB - PullRequest
1 голос
/ 08 сентября 2011

У меня есть база данных CouchDB с документами, представляющими 100 000 событий. Каждое событие имеет, помимо прочего, время, в которое оно произошло (хранится в виде массива [Год, месяц, день, час, минута, секунда]) и счет. Я хотел бы сделать график средних баллов по времени. Чтобы сделать это, я создал вид с картой, которая генерирует ключи, сгруппированные по интервалам, и функцию уменьшения, которая усредняет ключи в сегменте.

Это работает довольно хорошо. Когда запрашивается общее среднее значение, CouchDB возвращает результат почти мгновенно. Когда я собираю данные за день и получаю около сотни результатов, моя база данных CouchDB занимает пару сотен мсек, чтобы получить результат. Используя более 1000 сегментов, запрос занимает несколько секунд, чтобы вернуться. Пока этот запрос выполняется, мой процессор переходит на 100%, а мой диск довольно тихий.

Я немного озадачен этим замедлением. Поскольку сокращение всего, что происходит, кажется мгновенным, я пришел к выводу, что накладные расходы могут возникнуть при создании документа JSON с 1000+ записями. Разве CouchDB не способен быстро вернуть 1000 строк результатов?

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

Рекомендации

1 Ответ

2 голосов
/ 08 сентября 2011

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

Лучшее решение состоит в том, чтобы собрать сумму и количество предметов, и тогда вы можете легко получить среднее значение по клиенту.

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

Предполагая, что ваша функция карты такова;

function(doc) {
  emit([doc.year, doc.month, doc.day, doc.hour, doc.minute, doc.second], doc.score);
}

и ваша функция уменьшения равна;

_stats

тогда ваши результаты должны быть очень быстрыми (и масштабируемыми). Встроенная функция _stats будет возвращать результаты, подобные этому;

{"sum":2,"count":2,"min":1,"max":1,"sumsqr":2}

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

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