Маршрутизация запросов к данным

Содержание раздела
  1. Маршрутизации запросов к непартиционированным данным
  2. Определение категории и подкатегории запроса
  3. Стандартный порядок выбора типа датасорса
  4. Примеры запросов по категориям
    1. Реляционные запросы
    2. Запросы агрегации и группировки
    3. Запрос чтения по ключу
    4. Запрос неопределенной категории
  5. Примеры запросов по подкатегориям
    1. Запросы для одного узла
    2. Запросы для набора узлов
    3. Запросы для всех узлов
  6. Маршрутизация запросов к партиционированным таблицам
  7. Маршрутизация запросов к партициям

Раздел описывает маршрутизацию к данным логических таблиц, логических и материализованных представлений. Запрос к standalone-таблице всегда исполняется в том датасорсе, где расположена эта standalone-таблица.

Маршрутизации запросов к непартиционированным данным

О маршрутизации запросов к партиционированным таблицам и партициям см. в секциях ниже.

Запросы на чтение и выгрузку данных из логических таблиц, не участвующих в партиционировании данных, логических и материализованных представлений маршрутизируются следующим образом:

  • Если в запросе есть ключевое слово DATASOURCE_TYPE с датасорсом для исполнения запроса, запрос направляется в указанный датасорс.
  • Если в запросе нет DATASOURCE_TYPE:
    • Если запрос предназначен для материализованного представления и содержит ключевое слово FOR SYSTEM_TIME, а в целевом представлении нет данных за запрашиваемый момент времени, запрос перенаправляется к исходным таблицам датасорса-источника, на которых построено это представление.
    • Иначе:
      1. Определяются те датасорсы, в которых можно выполнить запрос, — выбираются датасорсы, содержащие данные всех запрашиваемых логических сущностей.
      2. Определяется категория или категория и подкатегория запроса (в зависимости от конфигурации; см. ниже).
      3. Выбирается наиболее оптимальный тип датасорса для исполнения запроса (см. ниже).
      4. Запрос направляется в один из датасорсов наиболее оптимального типа. Датасорс выбирается случайным образом среди всех датасорсов, которые относятся к наиболее оптимальному для запроса типу и содержат запрашиваемые сущности.

Подробнее о видах логических таблиц см. в разделе Логическая таблица > Виды таблиц.

Определение категории и подкатегории запроса

В зависимости от конфигурации система выбирает датасорс для исполнения запроса, учитывая категорию и подкатегорию запроса или только категорию запроса:

  • если в конфигурации задана секция параметров plugins.category.autoSelect, система использует настройки этой секции и при маршрутизации запроса учитывает как категорию, так и подкатегорию запроса;
  • иначе, если секция plugins.category.autoSelect не задана, система использует настройки секции plugins.category.mapping и учитывает только категорию запроса, без учета его подкатегории.

Категории запросов:

  1. Реляционный запрос (Relational) — запрос с ключевым словом JOIN и (или) подзапросами.
  2. Аналитический запрос (Analytical) — запрос с ключевым словом GROUP BY и агрегатными функциями.
  3. Запрос чтения по ключу (Dictionary) — запрос с условием WHERE на значения первичного ключа.
  4. Другой запрос (Undefined) — запрос, который не соответствует ни одной из предыдущих категорий.

Подкатегории запросов:

  • один узел (ShardOne) — запрос предназначается одному узлу кластера;
  • набор узлов (ShardSet) — запрос предназначается определенным узлам кластера (от 1 до всех);
  • все узлы (ShardAll) — запрос требует исполнения на всех узлах кластера.

Система определяет категорию запроса следующим образом: проверяет запрос на соответствие первой категории, и, если у него есть признаки этой категории, то система относит запрос к первой категории, иначе система проверяет запрос на соответствие второй категории и т.д. Например, запрос с ключевым словом JOIN соответствует первой категории («Реляционный запрос») независимо от наличия признаков других категорий — агрегации, группировки и чтения по ключу. Подкатегория запроса выбирается похожим образом с той разницей, что в этом случае порядок проверки неважен. Примеры запросов по категориям и подкатегориям и см. ниже.

Если при маршрутизации запросов нужно учитывать только категорию запросов, без учета подкатегории, скорректируйте конфигурацию ноды: удалите секцию параметров plugins.category.autoSelect и настройте секцию plugins.category.mapping.

Стандартный порядок выбора типа датасорса

По умолчанию при обработке запросов на чтение и выгрузку данных тип датасорса выбирается в порядке, описанном в таблице ниже.

Например, реляционный запрос, предназначенный для одного узла кластера, будет по возможности исполнен в датасорсе типа ADB. Если в хранилище нет ни одного датасорса типа ADB или в этих датасорсах нет запрашиваемых данных, — запрос будет по возможности исполнен в датасорсе типа ADP, и далее в указанном ниже порядке.

Такой порядок выбора датасорса в зависимости от типа эффективно использует возможности каждой СУБД. При необходимости его можно изменить в конфигурации ноды.

Категория запроса Порядок выбора типа датасорса для исполнения запроса
1. Реляционный запрос Один узел: 1. ADB, 2. ADP, 3. ADQM, 4. ADG
Набор узлов: 1. ADB, 2. ADP, 3. ADQM, 4. ADG
Все узлы: 1. ADB, 2. ADP, 3. ADQM, 4. ADG
2. Аналитический запрос Один узел: 1. ADQM, 2. ADB, 3. ADP, 4. ADG
Набор узлов: 1. ADQM, 2. ADB, 3. ADP, 4. ADG
Все узлы: 1. ADQM, 2. ADB, 3. ADP, 4. ADG
3. Запрос чтения по ключу Один узел: 1. ADG, 2. ADB, 3. ADP, 4. ADQM
Набор узлов: 1. ADG, 2. ADB, 3. ADP, 4. ADQM
Все узлы: 1. ADG, 2. ADB, 3. ADP, 4. ADQM
4. Другой запрос Один узел: 1. ADB, 2. ADP, 3. ADQM, 4. ADG
Набор узлов: 1. ADB, 2. ADP, 3. ADQM, 4. ADG
Все узлы: 1. ADB, 2. ADP, 3. ADQM, 4. ADG

Наиболее полный синтаксис запросов доступен в СУБД ADB и ADP. СУБД ADG и ADQM имеют ограничения на выполнение запросов, вызванные особенностями этих СУБД (см. Поддержка SQL).

Примеры запросов по категориям

Реляционные запросы

Реляционный запрос:

SELECT * FROM marketing.sales AS s
JOIN marketing.stores AS st ON s.store_id = st.id

Реляционный запрос, который включает агрегацию, группировку и чтение по ключу (st.id):

SELECT st.id, st.category, SUM(s.product_units) AS product_amount
FROM marketing.stores AS st
JOIN marketing.sales AS s ON st.id = s.store_id
WHERE st.id <> 10004
GROUP BY st.id, st.category
ORDER BY product_amount DESC

Запросы агрегации и группировки

Запрос агрегации и группировки:

SELECT s.product_code, SUM(s.product_units) AS product_amount
FROM marketing.sales AS s
GROUP BY s.product_code
ORDER BY product_amount ASC

Запрос агрегации и группировки, который включает чтение по ключу (s.id):

SELECT s.product_code, SUM(s.product_units) AS product_amount
FROM marketing.sales AS s
WHERE s.id > 20000
GROUP BY s.product_code

Запрос чтения по ключу

SELECT * FROM marketing.sales as s
WHERE s.id BETWEEN 1001 AND 2000

Запрос неопределенной категории

SELECT * FROM marketing.sales AS s
WHERE s.product_units > 2  

Примеры запросов по подкатегориям

Запросы для одного узла

Запрос к логическим таблицам transactions1 (шардирование по col1) и accounts1 (шардирование по colA):

SELECT * FROM transactions1 t
JOIN accounts1 a ON a.colA = t.col1
WHERE t.col1 = 1

Запрос к логической таблице transactions2 (шардирование col1 и col2):

SELECT * FROM transactions2 t
WHERE t.col1 = 1 AND t.col2 = 2 AND amount > 0  

Запросы к логическим таблицам transactions2 (шардирование по col1 и col2) и accounts2 (шардирование по colA и colB):

-- столбцы col1 and colA имеют один тип данных; столбцы col2 and colB также имеют один тип данных

-- запрос объединения таблиц
SELECT * FROM transactions2 t
JOIN accounts a ON a.id = t.account_id
WHERE t.col1 = 1 AND t.col2 = 2 AND a.colA = 1 AND t.colB = 2;

-- запрос с подзапросом
SELECT * FROM transactions2 t
WHERE t.account_id IN (
  SELECT id
  FROM accounts2 a
  WHERE t.col1 = 1 AND t.col2 = 2 AND a.colA = 1 AND a.colB = 2;

Запросы для набора узлов

Запрос к логическим таблицам transactions1 (шардирование по col1) и accounts1 (шардирование по colA):

SELECT * FROM transactions1
WHERE col1 IN (
  SELECT id
  FROM accounts1
  WHERE colA = 1
)

Запрос к логической таблице transactions2 (шардирование по col1 и col2):

SELECT * FROM transactions2 t
WHERE (t.col1 = 1 AND t.col2 = 2) OR ((t.col1 = 1 AND t.col2 = 1) AND amount > 0)

Запросы к логическим таблицам transactions2 (шардирование по col1 и col2) и accounts2 (шардирование по colA и colB):

-- столбцы col1 and colA имеют РАЗНЫЕ типы данных; столбцы col2 and colB имеют один тип данных
SELECT * FROM transactions2 t
JOIN accounts2 a ON a.id = t.account_id
WHERE t.col1 = 1 AND t.col2 = 2 AND a.colA = 1 AND t.colB = 2

Запросы для всех узлов

Запрос к логическим таблицам transactions1 (шардирование по col1) и accounts1 (шардирование по colA):

SELECT * FROM transactions1 t 
JOIN accounts1 a ON a.id = t.account_id
WHERE t.col1 = 1 OR a.colA = 1

Запрос к логической таблице transactions2 (шардирование по col1 и col2):

SELECT * FROM transactions2 t
WHERE (t.col1 = 1 AND t.col2 = 2) OR amount > 0 

Запросы к логическим таблицам transactions2 (шардирование по col1 и col2) и accounts2 (шардирование по colA и colB):

-- столбцы col1 and colA имеют один тип данных; столбцы col2 and colB также имеют один тип данных
SELECT * FROM transactions2 t
JOIN accounts2 a ON a.id = t.account_id
WHERE (t.col1 = 1 AND t.col2 = 2) OR (a.colA = 1 AND t.colB = 2)

Маршрутизация запросов к партиционированным таблицам

Запросы на чтение и выгрузку данных из партиционированных таблиц маршрутизируются следующим образом:

  1. По условиям, заданным с помощью ключевых слов JOIN и WHERE, выбирается подходящая партиция партиционированной таблицы.
  2. Если в запросе есть ключевое слово DATASOURCE_TYPE с датасорсом для исполнения запроса, запрос направляется в указанный датасорс.
  3. Если в запросе нет DATASOURCE_TYPE, запрос направляется в произвольный датасорс из тех, которые содержат данные выбранной партиции.

Маршрутизация запросов к партициям

Запросы на чтение и выгрузку данных напрямую из партиций маршрутизируются следующим образом:

  1. Если в запросе есть ключевое слово DATASOURCE_TYPE с датасорсом для исполнения запроса, запрос направляется в указанный датасорс.
  2. Иначе запрос направляется в произвольный датасорс из тех, которые содержат данные указанной партиции.