Как ускорить совокупный запрос БД Cosmos? - PullRequest
5 голосов
/ 01 мая 2019

Наш агрегатный запрос cosmos db кажется медленным и стоит больших RU. Вот подробности (плюс смотрите скриншот ниже): 2,4 с и 3222RU для подсчета результирующего набора из 414 тыс. Записей. Также это только для одного счета. Обычно мы хотели бы сделать сумму по многим полям одновременно (возможно только в пределах одного раздела), но производительность для этого намного хуже.

cosmos db query

В этой коллекции 2 миллиона записей. Мы используем Cosmos DB с SQL API. Эта конкретная коллекция разделена по коду страны, и во Франции имеется 414 732 записи («FR»), а остальные - в США. Размер документа в среднем составляет 917 байт, и, возможно, минимальное значение составляет 800 байт, максимальное - 1300 байт.

Обратите внимание, что мы также попробовали намного более разреженный ключ разделения, например, device_id (из которых здесь 2 миллиона, 1 документ на устройство), который имеет худшие результаты для этого запроса. Поле c.calcuated.flag1 просто представляет «состояние», в которое мы хотим вести подсчет (на самом деле у нас есть 8 состояний, которые я хотел бы обобщить).

Индексирование для этой коллекции является значением по умолчанию, которое использует «согласованный» режим индексации и индексирует все поля (и включает индексы диапазона для Number и String). Значение RU установлено на 20 000, и в БД нет других действий.

Так дайте мне знать ваши мысли по этому поводу. Можно ли использовать Cosmos DB для получения нескольких сумм или подсчетов по полям, не увеличивая наши расходы на RU и не занимая много времени? Хотя 2.4s не так уж и страшны, нам действительно нужны субсекундные запросы для такого рода вещей. Наше приложение (на основе IoT) часто нуждается в отдельных документах, но также иногда требует такого рода подсчетов по всем документам в стране.

Есть ли способ улучшить производительность?

Ответы [ 3 ]

0 голосов
/ 11 мая 2019

Две идеи:

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

SELECT COUNT(1) FROM c WHERE country_code="FR"

Важно! Поле calculated.flag1, если ононе постоянный, может выдать проблему - как для каждого документа / записи - механизм БД должен вычислить результат, следовательно, высокий RU.Можете ли вы оптимизировать рассчитанные поля?(разбить их или выполнить вычисления как часть запроса?)

Вторым предложением будет попытка определить составной индекс

{  
        "automatic":true,
        "indexingMode":"Consistent",
        "includedPaths":[  
            {  
                "path":"/*"
            }
        ],
        "excludedPaths":[  

        ],
        "compositeIndexes":[  
            [  
                {  
                    "path":"/country_code",
                    "order":"ascending"
                },
                {  
                    "path":"/calculated",
                    "order":"descending"
                }
            ]
        ]
    }

Также см. Примеры составных политик индексирования

И Управление политиками индексирования в Azure Cosmos DB , чтобы увидеть, где вы редактируете их

0 голосов
/ 12 мая 2019

Команда Cosmos DB внесла значительные изменения в производительность агрегации и порядок использования индексов.Это их стратегия индексирования "v2", и она была внедрена только недавно (она может быть доступна не для всех учетных записей, обратитесь в MSFT, если у вас есть более старая база данных, требующая обновления).

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

Теперь вы заметите, что время загрузки документа отображается как 0 мс, а размер полученного документа - 0 байт.Время загрузки, которое я могу подтвердить, действительно довольно быстрое, поэтому, возможно, оно меньше 1 мс при измерении со стороны сервера.И размер документа 0 имеет больше смысла, так как для этого не нужно извлекать документы (только подсчет на основе индекса).

Наконец, вы можете видеть, что количество RU уменьшилось с 3222 до 7,4 !!!!Разница довольно существенная.

Суммирование сразу по нескольким столбцам в пределах одного раздела теперь также достаточно производительно, и мы можем сделать около 8 сумм одновременно для 2 миллионов документов с ~ 50 RU, и это займет около 20-70 мспри измерении из конечной точки API функции (включая сетевое время).

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

enter image description here

0 голосов
/ 10 мая 2019

Для конкретного показанного запроса нет необходимости указывать имя таблицы, и вы можете попробовать limit 1 , некоторая производительность будет улучшена.Например:

SELECT COUNT(1) FROM c WHERE country_code="FR" AND calculated.flag=1 LIMIT 1

Кроме того, не забудьте тщательно проанализировать выполнение вашего запроса, я не уверен в Cosmos, но, как и в подходе PostreSQL, EXPLAIN ANALYSE.Также убедитесь, что вы используете лучший тип переменных , например, varchar (2) вместо varchar (3).Я бы порекомендовал изменить типы символов стран по номерам , если вы их фильтруете (как вы указали).Например, FR = 1, GR = 2 и так далее.Это также улучшит производительность.Наконец, если код страны и вычисляемый флаг связаны, создайте уникальную переменную, определяющую их.Если ничего из этого не работает, проверьте работоспособность клиента и даже аппаратное обеспечение.

...