|
| 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 | + |
| 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) |
0 commit comments