Query Hint¶
Query hints — это директивы или комментарии, которые явно подсказывают оптимизатору, как выполнять запрос. В настоящее время StarRocks поддерживает три типа hints: системные переменные (SET_VAR), пользовательские переменные (SET_USER_VARIABLE) и Join‑подсказки. Hints действуют только в пределах одного запроса.
System variable hint¶
С помощью SET_VAR можно установить одну или несколько системных переменных в операторах SELECT и SUBMIT TASK, а затем выполнить оператор. Также SET_VAR можно использовать в SELECT‑части других операторов, таких как CREATE MATERIALIZED VIEW AS SELECT и CREATE VIEW AS SELECT. Обратите внимание: если SET_VAR используется в SELECT внутри CTE, то SET_VAR не оказывает эффекта, даже если оператор успешно выполнен.
В сравнении с общим использованием системных переменных, действующих на уровне сессии, SET_VAR действует на уровне отдельного оператора и не влияет на всю сессию.
Синтаксис¶
[...] SELECT /*+ SET_VAR(key=value [, key = value]) */ ...
SUBMIT [/*+ SET_VAR(key=value [, key = value]) */] TASK ...
Примеры¶
Чтобы задать режим агрегации для агрегирующего запроса, используйте SET_VAR, установив системные переменные streaming_preaggregation_mode и new_planner_agg_stage:
SELECT /*+ SET_VAR (streaming_preaggregation_mode = 'force_streaming',new_planner_agg_stage = '2') */ SUM(sales_amount) AS total_sales_amount FROM sales_orders;
Чтобы указать time‑out выполнения для SUBMIT TASK, используйте SET_VAR и задайте insert_timeout:
SUBMIT /*+ SET_VAR(insert_timeout=3) */ TASK AS CREATE TABLE temp AS SELECT count(*) AS cnt FROM tbl1;
Чтобы указать time‑out подзапроса при создании materialized view, используйте SET_VAR в SELECT:
CREATE MATERIALIZED VIEW mv
PARTITION BY dt
DISTRIBUTED BY HASH(`key`)
BUCKETS 10
REFRESH ASYNC
AS SELECT /*+ SET_VAR(query_timeout=500) */ * from dual;
Указание системных переменных в вложенном запросе:
-- Hint в основном запросе
WITH t AS (SELECT region, sales_amount FROM sales_orders)
SELECT /*+ SET_VAR (streaming_preaggregation_mode = 'force_streaming', new_planner_agg_stage = '2') */
SUM(sales_amount) AS total_sales_amount
FROM t;
-- Hint во вложенном запросе
WITH t AS (
SELECT /*+ SET_VAR (streaming_preaggregation_mode = 'force_streaming') */
region, sales_amount
FROM sales_orders
)
SELECT SUM(sales_amount) AS total_sales_amount
FROM t;
User-defined variable hint¶
С помощью SET_USER_VARIABLE можно установить одну или несколько пользовательских переменных в операторах SELECT или INSERT. Если другой оператор содержит SELECT‑часть, вы также можете использовать SET_USER_VARIABLE в этом SELECT. Другими операторами могут быть SELECT и INSERT, но не CREATE MATERIALIZED VIEW AS SELECT и не CREATE VIEW AS SELECT. Начиная с v3.2.4, StarRocks поддерживает SET_USER_VARIABLE.
В сравнении с общим использованием пользовательских переменных, действующих на уровне сессии, SET_USER_VARIABLE действует на уровне отдельного оператора и не влияет на всю сессию.
Синтаксис¶
[...] SELECT /*+ SET_USER_VARIABLE(@var_name = expr [, @var_name = expr]) */ ...
INSERT /*+ SET_USER_VARIABLE(@var_name = expr [, @var_name = expr]) */ ...
Примеры¶
Следующий SELECT использует скалярные подзапросы select max(age) from users и select min(name) from users, поэтому можно задать их как пользовательские переменные через SET_USER_VARIABLE, а затем выполнить запрос:
SELECT /*+ SET_USER_VARIABLE (@a = (select max(age) from users), @b = (select min(name) from users)) */ * FROM sales_orders where sales_orders.age = @a and sales_orders.name = @b;
Join hint¶
В многотабличных Join‑запросах оптимизатор обычно выбирает оптимальный метод Join. В особых случаях вы можете использовать Join‑hint, чтобы явно предложить метод Join оптимизатору или отключить Join Reorder. На данный момент Join‑hint поддерживает предложение Shuffle Join, Broadcast Join, Bucket Shuffle Join или Colocate Join как метода выполнения. При использовании Join‑hint оптимизатор не выполняет Join Reorder, поэтому вам нужно выбрать меньшую таблицу в качестве правой. Кроме того, при предложении Colocate Join или Bucket Shuffle Join убедитесь, что распределение данных соответствуют требованиям этих методов — иначе hint не подействует.
Синтаксис¶
... JOIN { [BROADCAST] | [SHUFFLE] | [BUCKET] | [COLOCATE] | [UNREORDER]} ...
Join Hint не чувствителен к регистру.
Примеры¶
Shuffle Join
Если нужно, чтобы строки с одинаковыми значениями бакет‑ключей из таблиц A и B перед выполнением Join попали на одну машину, подскажите метод как Shuffle Join.
select k1 from t1 join [SHUFFLE] t2 on t1.k1 = t2.k2 group by t2.k2;Broadcast Join
Если таблица A — большая, а таблица B — маленькая, предложите Broadcast Join. Данные B полностью рассылаются на машины, где находятся данные A, и затем выполняется Join. По сравнению с Shuffle Join экономится стоимость перемешивания данных большой таблицы A.
select k1 from t1 join [BROADCAST] t2 on t1.k1 = t2.k2 group by t2.k2;Bucket Shuffle Join
Если выражение равенства в Join включает бакет‑ключ таблицы A, особенно когда обе — большие таблицы, можно предложить Bucket Shuffle Join. Данные таблицы B перемешиваются и отправляются на узлы, где расположены данные A, согласно распределению A, и затем выполняется Join. В сравнении с Broadcast Join, Bucket Shuffle Join существенно снижает объём передачи, потому что данные B перемешиваются глобально только один раз. Таблицы, участвующие в Bucket Shuffle Join, должны быть либо непартиционированными, либо colocated.
select k1 from t1 join [BUCKET] t2 on t1.k1 = t2.k2 group by t2.k2;Colocate Join
Если таблицы A и B принадлежат одной Colocation Group, заданной при создании таблиц, то строки с одинаковыми бакет‑ключами из A и B располагаются на одном BE‑узле. Когда равенство в Join содержит бакет‑ключи A и B, можно предложить Colocate Join. Данные с одинаковыми ключами объединяются локально, что уменьшает сетевые передачи и повышает производительность.
select k1 from t1 join [COLOCATE] t2 on t1.k1 = t2.k2 group by t2.k2;
Просмотр выбранного метода Join¶
Используйте EXPLAIN, чтобы проверить фактический метод Join. Если результат показывает соответствие метода Join вашему hint, значит hint сработал.
EXPLAIN select k1 from t1 join [COLOCATE] t2 on t1.k1 = t2.k2 group by t2.k2;
