aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Neporada <neporada@gmail.com>2022-06-06 23:38:17 +0300
committerAndrey Neporada <neporada@gmail.com>2022-06-06 23:38:17 +0300
commit924e91db3ec3da20d30e6e45892ea2785d88559e (patch)
treeda778ff6bcb038ee8ca9ddfa0039087aad097618
parent44d6cdd398b90433ee75c6473f2660937eb4b530 (diff)
downloadydb-924e91db3ec3da20d30e6e45892ea2785d88559e.tar.gz
[YQL-14723] Document SQL hints in general and COMPACT() hint in particular
ref:92d5f97024b6e929eb323ba9f0a09f678882d674
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md8
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md6
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md56
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md4
4 files changed, 65 insertions, 9 deletions
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md
index 659564f9992..261b2f0df7a 100644
--- a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md
@@ -7,11 +7,11 @@
{% endnote %}
-Сразу после `IN` можно указать модификатор `COMPACT`.
+Сразу после `IN` можно указать [хинт](../../lexer.md#sql-hints) `COMPACT`.
Если `COMPACT` не указан, то `IN` с подзапросом по возможности выполняется как соответствующий `JOIN` (`LEFT SEMI` для `IN` и `LEFT ONLY` для `NOT IN`).
-Наличие модификатора `COMPACT` форсирует in-memory стратегию выполнения: из содержимого правой части `IN` в памяти сразу строится хеш-таблица, по которой затем фильтруется левая часть.
+Наличие `COMPACT` форсирует in-memory стратегию выполнения: из содержимого правой части `IN` в памяти сразу строится хеш-таблица, по которой затем фильтруется левая часть.
-Модификатором `COMPACT` следует пользоваться с осторожностью. Поскольку хеш-таблица строится в памяти, то запрос может завершиться с ошибкой, если правая часть `IN` содержит много больших и/или различных элементов.
+Хинтом `COMPACT` следует пользоваться с осторожностью. Поскольку хеш-таблица строится в памяти, то запрос может завершиться с ошибкой, если правая часть `IN` содержит много больших и/или различных элементов.
{% if feature_mapreduce %}
Так как в YQL есть лимит на размер запроса в байтах (порядка 1Мб), для больших списков значений нужно прикладывать их к запросу через URL и использовать функцию [ParseFile](../../../builtins/basic.md#parsefile).
@@ -38,7 +38,7 @@ SELECT 1 IN $foo;
$values = (SELECT column + 1 FROM table);
SELECT * FROM my_table WHERE
-- фильтрация по in-memory хеш-таблице на основе table
- column1 IN COMPACT $values AND
+ column1 IN /*+ COMPACT() */ $values AND
-- с последующим LEFT ONLY JOIN с other_table
column2 NOT IN (SELECT other_column FROM other_table);
```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md
index 3ebdf0a1980..05d5de4b6ec 100644
--- a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md
@@ -1,6 +1,6 @@
-## GROUP COMPACT BY
+## COMPACT
-Позволяет более эффективно выполнять агрегацию в тех случаях, когда автору запроса заранее известно, что ни по одному из ключей агрегации не встречаются большие объемы данных (больше примерно гигабайт или миллионов строк). Если это предположение на практике окажется неверным, то операция оставляет за собой право упасть из-за превышения потребления оперативной памяти или работать значительно медленнее не-COMPACT версии.
+Наличие [SQL хинта](../../lexer.md#sql-hints) `COMPACT` непосредственно после ключевого слова `GROUP` позволяет более эффективно выполнять агрегацию в тех случаях, когда автору запроса заранее известно, что ни по одному из ключей агрегации не встречаются большие объемы данных (больше примерно гигабайт или миллионов строк). Если это предположение на практике окажется неверным, то операция оставляет за собой право упасть из-за превышения потребления оперативной памяти или работать значительно медленнее не-COMPACT версии.
В отличие от обычного GROUP BY, отключается стадия Map-side combiner и дополнительные Reduce для каждого поля с [DISTINCT](#distinct) агрегацией.
@@ -10,7 +10,7 @@ SELECT
key,
COUNT(DISTINCT value) AS count -- топ-3 ключей по количеству уникальных значений
FROM my_table
-GROUP COMPACT BY key
+GROUP /*+ COMPACT() */ BY key
ORDER BY count DESC
LIMIT 3;
```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md
index ad4cf43d14b..8547e7ca115 100644
--- a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md
@@ -77,6 +77,62 @@ SELECT 1 as `column with\n newline, \x0a newline and \` backtick `;
SELECT 1 as "column with "" double quoute"; -- имя колонки будет: column with " double quoute
```
+## SQL хинты {#sql-hints}
+
+SQL хинты – это специальные настройки, которые позволяют пользователю влиять на план выполнения запроса
+(например, включать/выключать определенные оптимизации, форсировать стратегию JOIN-а и т.п.).
+В отличие от [PRAGMA](../pragma.md), SQL хинты обладают локальным действием – они привязаны к определенной точке YQL запроса (обычно следуют после ключевого слова)
+и влияют только на соответствующий statement или даже его часть.
+SQL хинты представляют собой набор настроек "имя-список значений" и задаются внутри комментариев специального вида –
+первым символом комментария с SQL хинтами должен быть `+`:
+```sql
+--+ Name1(Value1 Value2 Value3) Name2(Value4) ...
+```
+Имя SQL хинта является должно состоять из алфавтно-цифровых ASCII символов и начинаться с буквы. Регистр букв в имени хинта игнорируется.
+После имени хинта в скобках задается произвольное количество значений, разделенных пробелами. В качестве значения может выступать произвольный набор символов.
+Если в наборе символов значения имеется пробел или скобка, то необходимо использовать одинарные кавычки:
+
+```sql
+--+ foo('value with space and paren)')
+```
+
+```sql
+--+ foo('value1' value2)
+-- эквивалетно
+--+ foo(value1 value2)
+```
+
+Одинарную кавычку внутри значения необходимо эскейпить путем дублирования:
+
+```sql
+--+ foo('value with single quote '' inside')
+```
+
+При наличии в списке хинтов двух (и более) хинтов с одинаковыми именами используется последний:
+```sql
+--+ foo(v1 v2) bar(v3) foo()
+-- эквивалетно
+--+ bar(v3) foo()
+```
+
+Неизвестные имена SQL хинтов (либо синтаксически некорректные хинты) никогда не вызывают ошибок – они просто игнорируется:
+```sql
+--+ foo(value1) bar(value2 baz(value3)
+-- из-за пропущенной закрывающей скобки в bar эквивалетно
+--+ foo(value1)
+```
+Такое поведение связано с нежеланием ломать написанные ранее валидные YQL запросы с комментариями, которые похожи на хинты.
+При этом синтаксически корректные SQL хинты в неожиданном для YQL месте вызывают предупреждение:
+
+```sql
+-- в данный момент хинты после SELECT не поддерживаются
+SELECT /*+ foo(123) */ 1; -- предупреждение 'Hint foo will not be used'
+```
+
+Хочется заметить, что SQL хинты – это именно подсказки оптимизатору, поэтому:
+* хинты никогда не влияют на результат запроса
+* по мере развития оптимизаторов в YQL вполне возможна ситуация, в которой хинт становится неактуальным и начнет игнорироваться (например, полностью поменялся алгоритм, который настраивался данным хинтом, либо оптимизатор настолько улучшился, что гарантированно выбирает оптимальное решение, поэтому какие-то ручные настройки будут скорее вредить)
+
## Строковые литералы {#string-literals}
Строковый литерал (константа) записывается как последовательность символов, заключенных в одинарные кавычки. Внутри строкового литерала можно использовать правила эскейпинга в стиле C:
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md
index b3613fadc5d..11408dbb3dd 100644
--- a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md
@@ -137,9 +137,9 @@ WINDOW w AS (
* Функции, вычисляемые на рамке окна `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING` либо `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`, реализованы эффективно (не требуют дополнительной памяти и вычисляются на разделе за O(размер раздела)).
-* Для рамки окна `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING` есть возможность выбрать стратегию выполнения в оперативной памяти, указав хинт `COMPACT` после ключевого слова `PARTITION`.
+* Для рамки окна `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING` есть возможность выбрать стратегию выполнения в оперативной памяти, указав [хинт](../lexer.md#sql-hints) `COMPACT` после ключевого слова `PARTITION`.
- Например: `PARTITION COMPACT BY key` или `PARTITION COMPACT BY ()` (в случае если `PARTITION BY` изначально отсутствовал).
+ Например: `PARTITION /*+ COMPACT() */ BY key` или `PARTITION /*+ COMPACT() */ BY ()` (в случае если `PARTITION BY` изначально отсутствовал).
При наличии хинта `COMPACT` потребуется дополнительная память в размере O(размер раздела), но при этом не возникнет дополнительной `JOIN` операции.