Запрос контейнера Azure Cosmos

ПРИМЕНИМО К: API SQL

В этой статье описывается, как запрашивать контейнеры (коллекции, графы и таблицы) в 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`

Каждая физическая секция имеет собственный индекс. Поэтому при выполнении запроса cross-partition в контейнере фактически выполняется один запрос для каждой физической секции. Azure Cosmos DB будет автоматически объединять результаты по различным физическим секциями.

Индексы в разных физических секциях друг от друга независимы. В Azure Cosmos DB глобальный индекс отсутствует.

Параллельный запрос между секциями

Пакеты SDK Azure Cosmos DB 1.9.0 и более поздних версий поддерживают параметры выполнения параллельных запросов. Параллельные запросы между секциями позволяют выполнять запросы с низкой задержкой.

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

  • MaxConcurrency: позволяет установить максимальное количество одновременных сетевых подключений к секциям контейнера. Если для параметра установить значение -1, пакет SDK будет регулировать степень параллелизма. Если  MaxConcurrency установлен на 0, для секций контейнера имеется одиночное интернет подключение.

  • MaxBufferedItemCount: задержка запросов на транзакции и использование памяти на стороне клиента. Если пропустить этот параметр или задать значение -1, пакет SDK будет регулировать число буферизованных элементов при параллельном выполнении запросов.

Из-за возможности Azure Cosmos DB параллелизации запросов cross-partition, задержка запросов обычно масштабируется по мере того, как система добавляет физические секции. Однако следует помнить, что единичная расценка за запрос будет значительно увеличиваться по мере увеличения общего числа физических секций.

При выполнении запроса cross-partition, по сути, выполняется отдельный запрос для отдельной физической секции. Хотя запросы cross-partition будут использовать индекс (если он доступен), они по-прежнему не так эффективны, как запросы in-partition.

Полезный пример

Вот аналог для лучшего понимания запросов cross-partition:

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

С помощью этого примера можно сравнивать запросы in-partition и cross-partition:

Запрос в секции

Если агент по доставке знает правильный адрес квартиры в комплексе (физическая секция), он может сразу же подъехать к нужному зданию. Агент может проверить список номеров квартир (индекс), и быстро доставить соответствующие пакеты. В этом случае агент не тратит время или усилия, на поиск квартир, и может легко проверить, находятся ли в них получатели пакетов.

Запрос cross-partition (fan-out)

Если агент по доставке не знает корректный номер квартиры в комплексе (физической секции), ему потребуется зайти в каждую отдельную квартиру и проверить список по всем номерам проживающих (индекс). После того как он заходит в каждую квартиру, он по-прежнему может обратиться к списку адресов жителей. Тем не менее, ему приходится пройти по всему списку квартир, независимо от того, находится ли получатели пакета там куда он заходит или нет. Вот как работают запросы cross-partition. Хотя он может использовать индекс (не нужно стучаться в каждую отдельную дверь), он должен отдельно проверить индекс по каждой физической секции.

Запрос cross-partition (охватывающий только несколько физических секций)

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

Сведите к минимуму число запросов cross-partition

Для большинства контейнеров неизбежно будет несколько запросов cross-partition. Наличие запросов cross-partition — это нормально! Почти все операции запроса поддерживаются в секциях (логические ключи секции и физические секции). Azure Cosmos DB также имеет много оптимизаций в механизме запросов и клиентских пакетах SDK для параллельного выполнения запросов в физических секциях.

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

Избежание применения запросов cross-partition обычно имеет большое значение только для больших контейнеров. Вам будет выставляться минимум (примерно) 2,5 единиц запросов при проверке индекса физической секции на предмет результатов, даже если ни один из элементов физической секции не соответствует фильтру запроса. Таким образом, при наличии только одной (или нескольких) физических секций запросы cross-partition не будут потреблять значительно больше запросов, чем в in-partition.

Число физических секций связано с объемом предоставляемых единиц запросов. Каждая физическая секция поддерживает до 10 000 подготовленных единиц запросов и может хранить до 50 ГБ данных. Azure Cosmos DB будет автоматически управлять физическими секциями. Количество физических секций в контейнере зависит от подготовленной пропускной способности и используемого хранилища.

Следует избегать запросов cross-partition, если рабочая нагрузка соответствует следующим критериям:

  • Вы планируете использовать более 30 000 единиц запросов
  • Вы планируете хранить более 100 ГБ данных

Дальнейшие действия

Чтобы узнать о секционировании в Azure Cosmos DB, ознакомьтесь со следующими статьями: