MongoDB count могут сильно замедлить API
Опубликовано 23 September 2016 в Разное
Иногда команда фронтенда или другие потребители API просят выводить в ручках общее число объектов. Если в качестве хранилища используется MongoDB, постарайтесь избежать этого. Такое поведение ручек может значительно их замедлить.
Я говорю о тех случаях, когда ответ API похож на тот, что расположен ниже, то ждите беды.
{
"total": XX,
"limit": ZZ,
"offset": YY,
"objects": [...]
}
Если коллекция достаточно большая, а запрос достаточно тяжелый, count будет работать непозволительно долго. Запрос find при этом может работать быстро: ему ведь надо вернуть всего-то с десяток объектов. Count будет шерстить весь набор объектов, подходящих под условия запроса.
Иногда добавление дополнительных условий в запрос, которые должны замедлить запрос (к примеру, поиск по регулярному выражению), но при этом сильно сокращают количество подходящих объектов, может даже ускорить ответ от API. Find так и будет возвращать с десяток объектов, а count будет пробегать гораздо меньше объектов.
Так какие же есть решения?
Во первых, если есть возможность поменять формат API, меняйте. Результат со ссылками на предыдущие и следующие результаты (как это делает Facebook API) может оказаться значительно быстрее.
{
"pre": "link-to-previous-x-objects",
"next": "link-to-next-x-objects",
"limit": x,
"objects": [...]
}
Второй возможных вариант: кэшировать total. Тогда API будет работать примерно как работают поисковые системы: иногда говорить клиенту, что в базе есть больше объектов, чем на самом деле. Во многих случаях это нормально. Особенно когда консистентность весьма условная.
В любом случае, все это имеет значение, если коллекция достаточно большая, объекты приличного размера, а запрос довольно сложный. Во всех остальных случаях, можно делать все, что заблагорассудится. Стоит только не забывать, что сервис может вырасти, а переделывать API потом будет очень сложно и дорого.
Возник вопрос? Мне всегда можно написать в Twitter: avkorablev