Запрос контейнера Azure Cosmos DB
ОБЛАСТЬ ПРИМЕНЕНИЯ: NoSQL
В этой статье описывается, как запрашивать контейнеры (коллекции, графы и таблицы) в Azure Cosmos DB. В частности, здесь рассматривается как работают запросы in-partition (запрос в секции) и cross-partition (запрос между секцииями) в Azure Cosmos DB.
Запрос в секции
Когда для получения данных из контейнеров отправляется запрос, в котором указан фильтр ключа секции, служба Azure Cosmos DB автоматически такой запрос обрабатывает. Эта служба направляет запрос в физические секции, соответствующие значениям ключей секций, указанным в фильтре.
Например, рассмотрим приведенный ниже запрос с фильтром равенства DeviceId
. Если этот запрос выполняется в контейнере, секционируемом по DeviceId
этому контейнеру, этот запрос фильтруется до одной физической секции.
SELECT * FROM c WHERE c.DeviceId = 'XMS-0001'
Как и в предыдущем примере, этот запрос также фильтрует одну секцию. Добавление фильтра Location
не изменяет следующий запрос:
SELECT * FROM c WHERE c.DeviceId = 'XMS-0001' AND c.Location = 'Seattle'
Вот запрос, имеющий фильтр диапазона для ключа секции и не относящийся к одиночной физической секции. Запрос in-partition должен иметь фильтр равенства, включающий ключ секции:
SELECT * FROM c WHERE c.DeviceId > 'XMS-0001'
Запрос между секциями
Следующий запрос не имеет фильтра для ключа секции (DeviceId
). Поэтому он должен выдумывать все физические секции, где он выполняется по индексу каждой секции:
SELECT * FROM c WHERE c.Location = 'Seattle`
Каждая физическая секция имеет собственный индекс. Таким образом, при выполнении запроса между секциями в контейнере вы эффективно выполняете один запрос на физическую секцию. Azure Cosmos DB автоматически агрегирует результаты в разных физических секциях.
Индексы в разных физических секциях друг от друга независимы. Глобальный индекс в Azure Cosmos DB отсутствует.
Параллельный запрос между секциями
Пакеты SDK Azure Cosmos DB 1.9.0 и более поздних версий поддерживают параметры выполнения параллельных запросов. Параллельные запросы между секциями позволяют выполнять запросы с низкой задержкой.
Вы можете управлять параллельным выполнением запросов, регулируя следующие параметры.
MaxConcurrency: позволяет установить максимальное количество одновременных сетевых подключений к секциям контейнера. Если для параметра установить значение
-1
, пакет SDK будет регулировать степень параллелизма.MaxConcurrency
Если задано значение0
, существует одно сетевое подключение к секциям контейнера.MaxBufferedItemCount: задержка запросов на транзакции и использование памяти на стороне клиента. Если пропустить этот параметр или задать значение -1, пакет SDK будет регулировать число буферизованных элементов при параллельном выполнении запросов.
Благодаря возможности Azure Cosmos DB параллелизировать запросы между секциями, задержка запросов обычно масштабируется, а также система добавляет физические секции. Однако плата за единицу запросов значительно увеличивается по мере увеличения общего числа физических секций.
При выполнении межсекционного запроса вы, по сути, выполняете отдельный запрос на отдельную физическую секцию. Хотя запросы между секциями используют индекс, если они доступны, они по-прежнему не столь эффективны, как запросы в секционировании.
Полезный пример
Ниже приведена аналогия, чтобы лучше объяснить межсекционные запросы:
Представьте себе, что вы водитель доставки, который должен доставлять пакеты в разные жилые комплексы. Каждый жилой комплекс имеет список в помещении, где есть все номера подразделений жителей. Каждую из этих квартир можно сравнить с физической секцией, а каждым список с индексом физической секции.
С помощью этого примера можно сравнивать запросы in-partition и cross-partition:
Запрос в секции (пример)
Если агент по доставке знает правильный адрес квартиры в комплексе (физическая секция), он может сразу же подъехать к нужному зданию. Водитель может проверить список номеров единиц (индекс) жилого комплекса и быстро доставить соответствующие пакеты. В этом случае водитель не тратит никакого времени или усилий вождения в жилой комплекс, чтобы проверить и узнать, живут ли получатели пакетов там.
Запрос cross-partition (fan-out)
Если водитель доставки не знает правильный жилой комплекс (физическая секция), он должен ехать в каждое жилое здание и проверить список со всеми номерами подразделений жителей (индекс). Когда водитель прибывает в каждый жилой комплекс, они по-прежнему могут использовать список адресов каждого жителя. Тем не менее, им нужно проверить список каждого жилого комплекса, независимо от того, живут ли получатели пакетов там или нет. В этом примере показано, как работают межсекционные запросы. Хотя они могут использовать индекс (то есть они не должны стучать на каждую дверь), они должны отдельно проверить индекс для каждой физической секции.
Запрос cross-partition (охватывающий только несколько физических секций)
Если водитель доставки знает, что все получатели пакетов живут в определенных нескольких жилых комплексах, им не нужно ездить к каждому из них. В то время как вождение в несколько жилых комплексах по-прежнему требует больше работы, чем посещение только одного здания, водитель доставки по-прежнему экономит значительное время и усилия. Если запрос содержит ключ секции в фильтре с IN
ключевым словом, он проверяет только соответствующие индексы физического раздела для данных.
Избегайте запросов между секциями
Для большинства контейнеров наличие некоторых запросов между секциями неизбежно, что нормально! Почти все операции запроса поддерживаются в секциях как для ключей логических секций, так и для физических секций. Azure Cosmos DB также имеет много оптимизаций в механизме запросов и клиентских пакетах SDK для параллельного выполнения запросов в физических секциях.
Для большинства сценариев с большим объемом чтения рекомендуется выбрать наиболее распространенное свойство в фильтрах запросов. Необходимо также убедиться, что ключ секции соответствует другим рекомендациям по выбору ключа секции.
Избежание применения запросов cross-partition обычно имеет большое значение только для больших контейнеров. При каждом проверке индекса физического раздела взимается не менее 2,5 ЕЗ, даже если элементы в физической секции не соответствуют фильтру запроса. Таким образом, если у вас есть только один (или несколько) физических секций, межсекционные запросы не используют значительно больше запросов ЕЗ, чем запросы в секциях.
Число физических секций связано с объемом предоставляемых единиц запросов. Каждая физическая секция поддерживает до 10 000 подготовленных единиц запросов и может хранить до 50 ГБ данных. Azure Cosmos DB автоматически управляет физическими секциями. Количество физических секций в контейнере зависит от подготовленной пропускной способности и используемого хранилища.
Следует попытаться избежать межсекционных запросов, если рабочая нагрузка соответствует следующим критериям:
- Вы планируете использовать более 30 000 единиц запросов
- Вы планируете хранить более 100 ГБ данных
Следующие шаги
Чтобы узнать о секционировании в Azure Cosmos DB, ознакомьтесь со следующими статьями:
- Partitioning and horizontal scaling in Azure Cosmos DB (Секционирование и горизонтальное масштабирование в Azure Cosmos DB)
- Создание искусственного ключа секции в Azure Cosmos DB