Skip to content

Commit 656b1b8

Browse files
pavelvelikhovblinkovfomichev3000
authored
YDBDOCS-743-optimizer: Optimizer documentation (#8522)
Co-authored-by: Ivan Blinkov <ivan@ydb.tech> Co-authored-by: Andrey Fomichev <andrey.fomichev@gmail.com>
1 parent 7f64b2d commit 656b1b8

File tree

8 files changed

+121
-3
lines changed

8 files changed

+121
-3
lines changed
Loading

ydb/docs/ru/core/concepts/glossary.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@
232232

233233
Как и в файловых системах, **папка**, **каталог**, **folder** или **directory** является контейнером для других сущностей. В случае {{ ydb-short-name }}, эти сущности могут быть [таблицами](#table) (включая [внешние таблицы](#external-table)), [топиками](#topic), другими папками и т.д.
234234

235+
### Оптимизатор запросов {#optimizer}
236+
237+
[**Оптимизатор запросов**](https://ru.wikipedia.org/wiki/Оптимизация_запросов_СУБД) — набор компонентов {{ ydb-short-name }}, отвечающих за преобразование логического представления запроса в конкретный физически исполнимый план получения запрошенного результата. Основная цель оптимизатора — выбрать среди всех возможных планов выполнения запроса достаточно эффективный с точки зрения прогнозируемого времени исполнения и потребления ресурсов кластера. Он описан более подробно в отдельной статье [{#T}](optimizer.md).
238+
235239
## Продвинутая терминология {#advanced-terminology}
236240

237241
Этот раздел объясняет термины, которые полезны для [{{ ydb-short-name }} контрибьюторов](../contributor/index.md) и пользователей, желающих глубже понять, что происходит внутри системы.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Оптимзация запросов в {{ ydb-short-name }}
2+
3+
В {{ ydb-short-name }} используются два типа оптимизаторов запросов: оптимизатор, основанный на правилах, и стоимостной оптимизатор. Стоимостной оптимизатор применяется для сложных запросов, как правило, аналитических ([OLAP](https://ru.wikipedia.org/wiki/OLAP)), а оптимизация по правилам работает на всех запросах.
4+
5+
План запроса представляет собой граф операций, таких как чтение данных из источника, фильтрация потока данных по предикату, а также более сложные операции, например [JOIN](../yql/reference/syntax/join.md) и [GROUP BY](../yql/reference/syntax/group_by.md). Оптимизаторы в {{ ydb-short-name }} принимают на вход начальный план запроса и преобразуют его в более эффективный план, эквивалентный начальному с точки зрения возвращаемого результата.
6+
7+
## Оптимизатор запросов основанный на правилах
8+
9+
Значительная часть оптимизаций в {{ ydb-short-name }} применима практически для любых планов запросов, что устраняет необходимость в анализе альтернативных планов и их стоимости. Оптимизатор, основанный на правилах состоит из набора эвристических правил, которые применяются всегда, когда это возможно. Например, практически в любом запросе полезно отфильтровывать неиспользуемые данные как можно раньше в плане исполнения. У каждого правила оптимизатора есть условия срабатывания и логика переписывания плана. Правила применяются итеративно до тех пор, пока существуют правила, применимые к текущему плану.
10+
11+
## Стоимостной оптимизатор запросов
12+
13+
Для более сложных оптимизаций, таких как выбор оптимального порядка джоина и алгоритмов джоинов используется стоимостной оптимизатор. Для каждого запроса стоимостной оптимизатор рассматривает большое количество альтернативных планов выполнения и выбирает из них лучший на основе оценки стоимости каждого варианта. На текущий момент этот оптимизатор работает только с планами, где есть операции [JOIN](../yql/reference/syntax/join.md). Он выбирает наилучший порядок исполнения этих операций, а также выбирает самую эффективную реализацию для каждого Join в плане.
14+
15+
Стоимостной оптимизатор состоит из трех основных компонент:
16+
17+
* Модуль перебора порядка соединений;
18+
* Модуль оценки стоимости плана;
19+
* Модуль статистики, на которую опирается оценка стоимости.
20+
21+
### Перебор порядка соединений
22+
23+
Текущий стоимостной оптимизатор в {{ ydb-short-name }} перебирает все полезные варианты соединения таблиц с помощью оператора Join, для которых определены условия соединений. Берется исходный план запроса, из которого строится граф соединений. В зависимости от исходного запроса могут получиться разные топологии этого графа, которые существенно влияют на объем множества альтернативных планов, которое требуется сравнить.
24+
25+
Например, вот типичный пример популярной топологии «звезда», где основная таблица фактов соединяется с многочисленными таблицами измерений:
26+
27+
```sql
28+
SELECT
29+
P.Brand,
30+
S.Country AS Countries,
31+
SUM(F.Units_Sold)
32+
33+
FROM Fact_Sales F
34+
INNER JOIN Dim_Date D ON (F.Date_Id = D.Id)
35+
INNER JOIN Dim_Store S ON (F.Store_Id = S.Id)
36+
INNER JOIN Dim_Product P ON (F.Product_Id = P.Id)
37+
38+
WHERE D.Year = 1997 AND P.Product_Category = 'tv'
39+
40+
GROUP BY
41+
P.Brand,
42+
S.Country
43+
```
44+
45+
В графе этого запроса все таблицы `Dim...` соединяются c таблицей фактов `Fact_Sales`:
46+
![Граф запроса](_assets/Star-Schema.png)
47+
48+
К типичным топологиям также относятся «цепочка» и «клика». «Цепочка» - это топология, где таблицы соединены друг с другом последовательно и каждая таблица участвует не более, чем в одном соединении. «Клика» — полностью связанный граф, где каждая таблица соединяется с другой.
49+
50+
На практике в OLAP запросах часто встречается топология, представляющая из себя комбинацию «звезы» и «цепочки», сложные топологии вроде «клики» встречаются очень редко.
51+
52+
Топология сильно влияет на количество альтернативных планов, которые требуется рассмотреть оптимизатору. Следовательно, стоимостной оптимизатор ограничивает количество соединений, которые сравниваются полным перебором, в зависимости от топологии исходного плана. Возможности точной оптимизации в {{ ydb-short-name }} приведены в следующей таблице:
53+
54+
| Топология | Кол-во поддерживаемых соединений |
55+
| --------- | -------------------------------- |
56+
| Цепочка | 110 |
57+
| Звезда | 18 |
58+
| Клика | 15 |
59+
60+
{{ ydb-short-name }} использует модификацию алгоритма [DPHyp](https://www.researchgate.net/publication/47862092_Dynamic_Programming_Strikes_Back) для перебора порядка соединений. Это самый современный алгоритм динамического программирования для оптимизации запросов. Посредством построения гиперграфов запросов он избегает перебора лишних альтернатив и позволяет оптимизировать планы с операторами `JOIN`, сложными предикатами, а также с операторами `GROUP BY` и `ORDER BY`.
61+
62+
### Оценка стоимости планов
63+
64+
Сравнение сложности планов основано на стоимостной функции, которая оценивает ресурсоёмкость каждой операции плана. Основные параметры стоимостной функции — это прогнозы размера входных данных для каждого оператора и размера его результата. Эти прогнозы выполняются на основе статистики, собранной по таблицам {{ ydb-short-name }}, а также анализа самого плана.
65+
66+
### Статистики для стоимостного оптимизатора {#statistics}
67+
68+
Стоимостной оптимизатор использует статистики как по таблице целиком, так и по отдельным колонкам. {{ ydb-short-name }} собирает и поддерживает статистку в актуальном состоянии в фоновом режиме. Форсировать сбор статистики можно с помощью команды [ANALYZE](../yql/reference/syntax/analyze.md).
69+
70+
Текущий набор статистик по таблицам:
71+
72+
* Количество записей таблицы;
73+
* Размер таблицы в байтах.
74+
75+
Текущий набор статистик по колонкам:
76+
77+
* [Count-min sketch](https://en.wikipedia.org/wiki/Count%E2%80%93min_sketch).
78+
79+
### Текущие уровни стоимостной оптимизации
80+
81+
В {{ ydb-short-name }} можно выставить уровень стоимостной оптимизации через прагму [CostBasedOptimizationLevel](../yql/reference/syntax/pragma.md#costbasedoptimizationlevel)

ydb/docs/ru/core/concepts/toc_i.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ items:
2525
href: cluster/common_scheme_ydb.md
2626
- name: Дисковая подсистема кластера
2727
href: cluster/distributed_storage.md
28+
- name: Оптимизатор запросов
29+
href: optimizer.md
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
{% if tech %}
2-
31
## YDB
42

3+
### `ydb.CostBasedOptimizationLevel` {#costbasedoptimizationlevel}
4+
5+
| Уровень | Поведение оптимизатора |
6+
| ------- | ---------------------- |
7+
| 0 | Cтоимостный оптимизатор выключен |
8+
| 1 | Cтоимостный оптимизатор выключен, считаются предсказания оптимизатора |
9+
| 2 | Cтоимостный оптимизатор включается только для запросов, где участвуют [колоночные таблицы](../../../../../concepts/glossary.md#column-oriented-table) |
10+
| 3 | Cтоимостный оптимизатор включается для всех запросов, но для строковых таблиц предпочитается алгоритм джоина LookupJoin |
11+
| 4 | Cтоимостный оптимизатор включен для всех запросов |
12+
13+
{% if tech %}
14+
515
### `kikimr.IsolationLevel`
616

717
| Тип значения | По умолчанию |
@@ -10,4 +20,4 @@
1020

1121
Экспериментальная pragma, позволяет ослабить уровень изоляции текущей транзакции в YDB.
1222

13-
{% endif %}
23+
{% endif %}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# ANALYZE
2+
3+
`ANALYZE` форсирует сбор табличной и колоночной статитстики для оптимизатора запросов.
4+
5+
Синтаксис:
6+
7+
```yql
8+
ANALYZE <path_to_table> [ (<column_name> [, ...]) ]
9+
```
10+
11+
В результате выполнения команды будет собрана и актуализирована статистика по указанной таблицам в целом, а также по всем или указанным колонкам. Комадна ANALYZE синхронная, то есть эта команда завершится только тогда, когда будет собрана и актуализирована указанная статистика.
12+
13+
* `path_to_table` — путь к конкретной таблице, для которой требуется форсированный сбор статистики
14+
* `column_name` — форсировать сбор статистики только по определённым колонкам таблицы
15+
16+
Текущий набор статистик указан в разделе [{#T}](../../../concepts/optimizer.md#statistics).

ydb/docs/ru/core/yql/reference/yql-core/syntax/pragma.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
{% include [x](_includes/pragma/files.md) %}
1010

11+
{% if backend_name == "YDB" %}
12+
1113
{% include [x](_includes/pragma/ydb.md) %}
1214

15+
{% endif %}
16+
1317
{% include [x](_includes/pragma/debug.md) %}

ydb/docs/ru/core/yql/reference/yql-core/syntax/toc_i.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ items:
99
- { name: ALTER VIEW, href: alter-view.md, when: feature_view }
1010
- { name: ALTER TOPIC, href: alter-topic.md, when: feature_topic_control_plane }
1111
- { name: ALTER USER, href: alter-user.md, when: feature_user_and_group }
12+
- { name: ANALYZE, href: analyze.md, when: backend_name == "YDB" }
1213
- { name: CREATE ASYNC REPLICATION, href: create-async-replication.md, when: feature_async_replication }
1314
- { name: CREATE GROUP, href: create-group.md, when: feature_user_and_group }
1415
- { name: CREATE EXTERNAL DATA SOURCE, href: create-external-data-source.md,when: feature_federated_queries}

0 commit comments

Comments
 (0)