Выбор датасорса для исполнения запроса
Содержание раздела
При исполнении запроса на чтение или выгрузку данных система выбирает один или несколько подходящих датасорсов. Подходящими датасорсами считаются:
- [для запросов с FROM] включенные датасорсы, содержащие данные всех сущностей запроса;
- [для запросов без FROM] датасорсы в любом статусе, кроме
not healthy.
Порядок выбора датасорса зависит от наличия приоритета у запроса:
- если приоритет назначен (внешней системой или системой Prostore) и для него заданы настройки балансировки, датасорс выбирается с балансировкой;
- иначе датасорс выбирается без балансировки.
Выбор датасорса с балансировкой
Для запросов с назначенным приоритетом система выбирает датасорс с применением балансировки, как описано в таблице ниже. При выборе не учитывается оптимальный тип датасорса.
| Характеристика запроса (по убыванию приоритета) | Датасорсы, где исполняется запрос |
|---|---|
| 1. Содержит DATASOURCE_TYPE | Указанный в запросе. Должен подходить для всех сущностей запроса и входить в число настроенных для приоритета запроса, иначе — ошибка |
| 2. Содержит снапшот-таблицы с set.strict.consistency.enable = true | Первый по алфавиту из подходящих для каждой такой таблицы. Должен быть общим для всех таких таблиц, подходить для остальных сущностей запроса и входить в число настроенных для приоритета запроса, иначе — ошибка |
| 3. Остальные случаи | Подходящий из настроенных для приоритета запроса. Если таких несколько, критерии применяются последовательно, пока не останется один датасорс:
|
* Запросы с одинаковым значением queryId при одинаковом списке подходящих датасорсов исполняются в одном и том же датасорсе (если он включен; иначе выбирается другой).
Выбор датасорса без балансировки (базовый алгоритм)
Для запросов без назначенного приоритета система выбирает датасорс без применения балансировки, как описано в таблице ниже. При выборе может учитываться оптимальный тип датасорса.
| Характеристика запроса (по убыванию приоритета) | Датасорсы, где исполняется запрос |
|---|---|
| 1. Содержит DATASOURCE_TYPE | Указанный в запросе. Должен подходить для всех сущностей запроса, иначе — ошибка |
| 2. Содержит снапшот-таблицы с set.strict.consistency.enable = true | Первый по алфавиту из подходящих для каждой такой таблицы. Должен быть общим для всех таких таблиц и подходить для остальных сущностей запроса, иначе — ошибка |
| 3. Остальные случаи | Определенный как подходящий. Если таких несколько, критерии применяются последовательно, пока не останется один датасорс:
|
* Запросы с одинаковым значением queryId при одинаковом списке подходящих датасорсов исполняются в одном и том же датасорсе (если он включен; иначе выбирается другой).
Оптимальный тип датасорса для категории запроса
При обработке запросов без дополнительных условий на датасорс (без приоритета запроса, DATASOURCE_TYPE, партиционированных таблиц, а также без снапшот-таблиц со строгим уровнем консистентности) система определяет категорию запроса и выбирает датасорс наиболее оптимального типа для этой категории.
Определение категории запроса
Категория запроса определяется так (по убыванию приоритета):
- Содержит
JOINи (или) подзапросы → реляционный. - Содержит
GROUP BYи агрегатные функции → аналитический. - Содержит условие
WHEREна первичный ключ → чтение по ключу. - Не содержит сущности → запрос без
FROM. - Остальные случаи → другой.
Запрос относится к категории с наивысшим приоритетом, признаки которой у него есть. Например, запрос с JOIN всегда реляционный, даже если содержит другие признаки.
Примеры запросов по категориям
Реляционные запросы:
-- реляционный запрос без признаков других категорий
SELECT * FROM marketing.sales AS s
JOIN marketing.stores AS st ON s.store_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;
-- аналитический запрос с чтением по ключу
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
Запрос без FROM:
SELECT 1
Другой запрос:
SELECT * FROM marketing.sales AS s
WHERE s.product_units > 2
Оптимальные типы датасорсов
По умолчанию оптимальный тип датасорса в зависимости от категории запроса выбирается, как показано в таблице ниже. Такой порядок учитывает сильные стороны каждого типа и может быть изменен в конфигурации.
| Категория запроса | Порядок выбора типа датасорса |
|---|---|
| Реляционный запрос (Relational) | 1. ADB, 2. ADP, 3. ADQM, 4. ADG |
| Аналитический запрос (Analytical) | 1. ADQM, 2. ADB, 3. ADP, 4. ADG |
| Запрос чтения по ключу (Dictionary) | 1. ADG, 2. ADB, 3. ADP, 4. ADQM |
Без FROM (Without from) | 1. ADP, 2. ADB, 3. ADQM, 4. ADG |
| Другой запрос (Undefined) | 1. ADB, 2. ADP, 3. ADQM, 4. ADG |
Например, для реляционного запроса предпочтение отдается типу ADB, но, если в хранилище нет ADB-датасорсов или в них нет запрашиваемых данных, — типу ADP и далее по таблице.
Основные причины ошибок при выборе датасорсов
Обработка запроса может завершиться ошибкой при следующих основных проблемах с выбором датасорса:
- выбор с балансировкой и без:
- нет датасорса, подходящего для всех сущностей запроса;
- датасорс, выбранный по строгому критерию (
DATASOURCE_TYPE, снапшот-таблица со строгой консистентностью), не подходит для остальных сущностей запроса; - нет общего датасорса для всех снапшот-таблиц со строгой консистентностью в запросе;
- только выбор с балансировкой:
- ни один датасорс, подходящий для всех сущностей запроса и (или) выбранный по строгому критерию, не входит в число настроенных для приоритета запроса.