Когда крупный автопроизводитель проектирует новую модель автомобиля, он редко изобретает двигатель с нуля — чаще берётся проверенный, отработанный годами силовой агрегат, который просто ставится под капот. Владельцу машины не нужно разбираться в устройстве двигателя, чтобы ей управлять: он поворачивает ключ и едет, но иногда полезно заглянуть под капот — понять, почему машина ведёт себя так, а не иначе, — но чинить двигатель самостоятельно от него никто не ждёт.
Похожая история с AW BI и индексами моделей. Под капотом системы работает ClickHouse — проверенный, широко используемый движок хранения аналитических данных. AW BI не изобретает свою механику индексации, а даёт удобный интерфейс поверх готового и надёжного «двигателя». Вам не нужно писать код или SQL-запросы — все настройки индекса делаются несколькими кликами. Но чтобы понимать, почему выбор и порядок полей влияет на скорость дашбордов, стоит хотя бы раз заглянуть под капот и посмотреть, как там всё устроено.
Сегодня мы говорим именно на языке «под капотом» — но помните: в самом AW BI всё это скрыто за простым интерфейсом, и в этом вся прелесть системы.
План статьи:
- Кейс: почему дашборд с заказами стал открываться медленнее
- Что делает настройка «Индексы» в AW BI
- Пошаговая настройка в интерфейсе
- Что происходит под капотом: как ClickHouse хранит и постоянно оптимизирует данные
- Первичный ключ в ClickHouse - отличия от других БД
- Разреженный индекс: как ClickHouse ищет данные по запросу
- Как выбирать порядок полей на примере нашего кейса
- Если вы привыкли к индексам в других системах
- Как это влияет на загрузку данных (push to ClickHouse)
- Ограничения индексации в AW BI
- Итог
1. Кейс: почему дашборд с заказами стал открываться медленнее
Возьмём условную модель «Заказы» по сети розничных магазинов: регион, категория товара, дата заказа, сумма заказа. Дашборд построен на нескольких виджетах — все они фильтруются по региону и смотрят на динамику по датам, часть виджетов также фильтрует по категории товара. По мере роста таблицы виджеты стали заметно медленнее прогружаться.
Обратите внимание: этот кейс синтетический — используем датасет только для того, чтобы показать сам интерфейс настройки индекса в AW BI и на конкретном примере объяснить механику выбора полей. Общий принцип от этого не меняется.
2. Что делает настройка «Индексы» в AW BI
«Индекс — это объект базы данных, который служит для ускорения поиска информации. Его структура оптимизирована под задачи поиска.»
Настройка «Индексы» задает ключ сортировки ORDER BY таблицы модели в ClickHouse. Поскольку отдельный PRIMARY KEY не задается, ClickHouse использует этот же набор полей как первичный ключ, на основе которого строится разреженный индекс. Порядок выбранных полей определяет порядок полей в составном ключе и влияет на эффективность фильтрации данных.
Настройка не создает отдельный вторичный индекс и не выполняет команду CREATE INDEX. Она определяет физический порядок данных в таблице модели.
3. Датасет для демонстрации
Для примера возьмём условную таблицу заказов розничной сети. Датасет не публикуется вместе со статьёй — он нужен только для того, чтобы показать интерфейс настройки на реальных полях.
| Поле | Тип | Описание |
|---|---|---|
order_id |
Целое число | Уникальный номер заказа |
region |
Строка | Регион доставки (Москва, Санкт-Петербург и т.д.) |
category |
Строка | Категория товара |
order_date |
Дата | Дата оформления заказа |
amount |
Дробное число | Сумма заказа |
delivery_days |
Целое число | Срок доставки в днях |
4. Что происходит под капотом: как ClickHouse хранит и постоянно оптимизирует данные
Официальная документация ClickHouse так описывает роль движка хранения:
«The table engine determines how and where the data is stored, which queries are supported, whether or not the data is replicated… for a simple table on a single-node ClickHouse server, MergeTree is your likely choice.»
Что в переводе на русский означает: «Движок таблицы определяет, как и где хранятся данные, какие запросы поддерживаются и реплицируются ли данные… для простой таблицы на одном сервере ClickHouse, скорее всего, подойдёт движок MergeTree». Именно на этом движке строятся таблицы моделей AW BI в ClickHouse.
Как проходит запись данных (это и есть шаг push to ClickHouse при синхронизации модели):
- Каждая вставка данных создаёт новый парт (part) — физический набор файлов на диске, где данные уже отсортированы по ключу индекса и сжаты.
- Со временем партов становится много, и в фоне постоянно работает процесс merge — он объединяет мелкие парты в более крупные, сохраняя общую сортировку.
- Старые парты-источники после слияния помечаются неактивными и со временем удаляются — место на диске освобождается автоматически.
Это объясняет, почему индекс требует пересборки данных: сортировка — это свойство самих партов на диске, а не отдельная надстройка, которую можно применить «задним числом» без переупаковки данных.
Гранулы. Данные внутри каждого парта разбиваются на гранулы — минимальные неделимые блоки, которые ClickHouse считывает с диска. Размер гранулы задаётся параметром index_granularity, по умолчанию 8192 строки (в части источников ClickHouse также указывается альтернативный порог — 10 МБ данных, смотря что наступит раньше). Именно на гранулы опирается индекс
«Выбор размера гранулы — это поиск баланса. Слишком маленькие гранулы сделают поиск очень точным, но раздуют индекс. Слишком большие гранулы уменьшат индекс, но заставят ClickHouse “пролистывать” много лишних данных.»
Благодаря этому механизму — постоянному фоновому слиянию партов и разбиению на гранулы — данные в таблице всегда оптимизируются для чтения, что позволяет:
- быстро находить нужные данные, используя индекс;
- считывать меньше лишней информации, пропуская целые блоки;
- эффективно работать с диском, читая один большой фрагмент вместо сотен маленьких.
5. Первичный ключ в ClickHouse - отличия от других БД
В официальной документации ClickHouse про роль первичного ключа сказано следующее (в переводе): «В отличие от традиционных реляционных баз данных, где первичный ключ — это в первую очередь ограничение для обеспечения уникальности записи, в ClickHouse его главная задача — служить основой для разреженного индекса, позволяющего быстро находить нужные диапазоны данных».
6. Разреженный индекс: как ClickHouse ищет данные по запросу
Мы уже знаем, что данные внутри парта разбиты на гранулы. Для первой строки каждой гранулы ClickHouse создаёт «засечку» — значение полей индекса на начало этой гранулы. Это и есть разреженный индекс: отметки не на каждую строку, а по одной на гранулу — что-то вроде оглавления книги, где указано не «строка 4521», а «глава 5 начинается на странице 83».
Возьмём наш индекс (region, order_date, category) и разберём, что происходит с разными запросами:
Фильтр по региону (первое поле индекса). ClickHouse выполняет быстрый бинарный поиск по засечкам и сразу находит нужный диапазон гранул, полностью пропуская все остальные регионы.
Фильтр по региону и дате вместе (префикс индекса). Сначала сужается диапазон по региону, затем внутри найденных гранул анализируется диапазон дат — отсекается ещё часть данных. Читается заметно меньше, чем в первом случае.
Фильтр только по категории (поле, которое не идёт первым в индексе, без региона в условии).
Фильтр только по категории, без условий по региону и дате, не использует начальный префикс ключа. Поэтому первичный индекс, как правило, работает значительно менее эффективно: ClickHouse может потребоваться проверить большое количество гранул. В неблагоприятном случае объем чтения приближается к полному сканированию таблицы. Фактический результат зависит от распределения значений, поэтому последующее поле ключа нельзя считать гарантированно бесполезным.
7. Как выбирать порядок полей на примере нашего кейса
Общая рекомендация для аналитических запросов, которые фильтруют широкие срезы данных: располагать поля в порядке возрастания кардинальности — от низкой к высокой. Кардинальность — это количество уникальных значений в столбце.
Применительно к нашему кейсу:
region— низкая кардинальность (несколько регионов);order_date— кардинальность выше (десятки-сотни уникальных дат), но виджеты почти всегда фильтруют и по региону, и по диапазону дат вместе;category— кардинальность похожа на регион по количеству значений, но используется как фильтр реже и не во всех виджетах.
Поэтому логичный порядок — region → order_date → category: сначала поле, которое режет данные сильнее всего и используется почти в каждом запросе, затем поле с диапазонной фильтрацией, которое почти всегда идёт в связке с первым, и в конце — поле, которое фильтруется реже остальных.
- Откройте модель в режиме редактирования.
- Нажмите на кнопку настроек, чтобы открыть окно настроек модели.

- Перейдите в подраздел «Параметры».
- Отметьте флажками нужные поля в том порядке, в котором они должны идти в индексе. Если нужно выбрать все поля сразу, используйте кнопку «Выбрать все» — но для реальных моделей это редко оправдано.
- Нажмите «Сохранить».
- Запустите синхронизацию модели — только после неё индекс фактически применится к данным в ClickHouse.
Для нашего кейса порядок будет другой: region → order_date → category.
Важное исключение: если бы у нас 90% запросов на дашборде были точечными по конкретной категории (WHERE category = '...', без региона и даты), разумнее было бы поставить category первой в индексе — для точечных обращений это быстрее, чем поиск по низкокардинальным полям. Правило про кардинальность — это ориентир для типичных широких аналитических запросов, а не универсальный закон. Главный критерий всегда один: какие поля реально используются как фильтры в ваших виджетах и в каком порядке они комбинируются.
8. Если вы привыкли к индексам в других системах
Если у вас есть опыт работы с индексами в других базах данных, стоит иметь в виду: логика в ClickHouse — а значит, и в AW BI — устроена немного иначе. Два момента, которые стоит держать в голове:
- Первичный ключ здесь — это буквально порядок физической сортировки самих строк таблицы на диске, а не отдельная надстройка над ней.
- По сути это один составной ключ, и порядок полей в нём принципиален — в отличие от подхода, где можно независимо создать несколько разных индексов под разные запросы.
9. Как это влияет на загрузку данных (push to ClickHouse)
- При каждой синхронизации модели данные записываются новыми кусками, уже отсортированными по полям индекса — сортировка выполняется на этапе записи.
- Фоновое слияние продолжает пересортировывать и объединять данные уже после записи.
- Чем больше полей выбрано в индексе, тем дороже операция сортировки при синхронизации — это прямая нагрузка на этапе загрузки.
Получается прямой компромисс: индекс — это баланс между временем синхронизации модели и скоростью последующего чтения данных виджетами. Удачный порядок полей = быстрее дашборды, но дольше синхронизация; поля выбраны без учёта реальных фильтров = синхронизация всё равно дороже, а выигрыша при чтении нет.
10. Ограничения индексации в AW BI
Индексация в интерфейсе AW BI недоступна для трёх типов моделей — но по разным причинам, и это важно не путать:
Инкрементальная загрузка. Индекс не создаётся, потому что требует полной пересборки таблицы при каждой синхронизации, а инкрементальная загрузка построена на точечной дозаписи изменений.
Live-модели. Настройки «Индексы» для live-моделей в интерфейсе AW BI нет — но это не значит, что индексация здесь не нужна или невозможна в принципе. Live-модель обращается напрямую к базе данных-источнику, минуя собственное хранилище ClickHouse в AW BI, поэтому оптимизация чтения находится на стороне этой внешней базы. Индексы для live-моделей нужно настраивать не в AW BI, а в самой базе-источнике, к которой модель обращается напрямую.==
Ассоциативные модели. Отдельной настройки индекса на уровне самой ассоциативной модели нет — и это логично: ассоциативная модель не хранит физическую таблицу данных сама по себе, а связывает между собой логические модели, которые в неё входят. Индексы нужно настраивать в тех логических моделях, из которых состоит ассоциативная модель, а не в ней самой.==
Отдельно от этих случаев — кастомизация процесса синхронизации: если она настроена так, что таблица модели не пересоздаётся целиком при синхронизации, индекс тоже не сработает — по той же причине, что и с инкрементальной загрузкой.
11. Итог
В целом наличие индекса в полной мере вам не гарантирует ускорения всех виджетов и фильтров. Результат зависит от реальных условий запросов, распределения значений и доли гранул, которые ClickHouse сможет исключить. Эффективность настройки рекомендуется проверять на характерных сценариях и реальном объеме модели.
Индексы в AW BI — это в свою очередь простой интерфейс поверх серьёзной и проверенной механики ClickHouse: вам не нужно писать ни строчки кода, чтобы ей воспользоваться. Но одно решение остаётся за вами — порядок полей, и именно оно определяет, получите ли вы реальный выигрыш в скорости дашбордов или просто заплатите временем синхронизации без отдачи. Выбирайте поля исходя из того, как реально фильтруются ваши виджеты, — и двигатель под капотом сделает всё остальное сам.





