Маршрутизация запросов к данным
Содержание раздела
Раздел описывает маршрутизацию к данным логических таблиц, логических и материализованных представлений.
Запрос к standalone-таблице всегда исполняется в том датасорсе, где расположена эта standalone-таблица.
Запросы на чтение и выгрузку данных маршрутизируются следующим образом:
- Если в запросе указано ключевое слово DATASOURCE_TYPE с датасорсом для исполнения запроса, запрос направляется в указанный датасорс.
- Иначе:
- Определяются те датасорсы, в которых можно выполнить запрос, — выбираются датасорсы, содержащие данные всех запрашиваемых логических сущностей.
- Определяется категория или категория и подкатегория запроса (в зависимости от конфигурации системы; см. ниже).
- Выбирается наиболее оптимальный тип датасорса для исполнения запроса (см. ниже).
- Запрос направляется в один из датасорсов наиболее оптимального типа. Датасорс выбирается случайным образом среди всех датасорсов, которые относятся к наиболее оптимальному для запроса типу и содержат запрашиваемые сущности.
- Если запрос обращается к материализованному представлению, он проходит дополнительные этапы маршрутизации.
Определение категории и подкатегории запроса
В зависимости от конфигурации системы система выбирает датасорс для исполнения запроса, учитывая категорию и подкатегорию запроса или только категорию запроса:
- если в конфигурации системы задана секция параметров
plugins.category.autoSelect
, система использует настройки этой секции и при маршрутизации запроса учитывает как категорию, так и подкатегорию запроса; - иначе, если секция
plugins.category.autoSelect
не задана, система использует настройки секцииplugins.category.mapping
и учитывает только категорию запроса, без учета его подкатегории.
Категории запросов:
- Реляционный запрос (Relational) — запрос с ключевым словом JOIN и (или) подзапросами.
- Аналитический запрос (Analytical) — запрос с ключевым словом GROUP BY и агрегатными функциями.
- Запрос чтения по ключу (Dictionary) — запрос с условием WHERE на значения первичного ключа.
- Другой запрос (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)
Маршрутизация запросов к материализованным представлениям
Запросы к данным материализованных представлений проходят все этапы маршрутизации, описанные выше, и затем — дополнительные этапы:
- Если для материализованного представления не указано ключевое слово FOR SYSTEM_TIME, запрос направляется в датасорс, где размещены данные этого представления. Из представления выбираются данные последней версии на момент последней синхронизации представления.
- Иначе, если ключевое слово
FOR SYSTEM_TIME
указано, система проверяет, есть ли в представлении данные за запрашиваемый момент времени:- Если в запросе есть ключевое слово
DATASOURCE_TYPE
, а данных за запрашиваемый момент времени в представлении нет, в ответе возвращается исключение. - Если в запросе нет ключевого слова
DATASOURCE_TYPE
:- Если данные есть в представлении, запрос направляется в датасорс, где размещены данные этого представления.
- Иначе запрос направляется к исходным таблицам датасорса-источника, на которых построено представление.
- Если в запросе есть ключевое слово
В запросах к материализованным представлениям доступны не все выражения с ключевым словом FOR SYSTEM_TIME
. Подробнее см. в разделе SELECT > Доступность значений FOR SYSTEM_TIME.