dbt

Средний уровень

Как ускорить модели dbt и снизить расходы на Snowflake/BigQuery?

В проекте dbt время выполнения и счёт за хранилище — почти одна и та же метрика под разными именами: исправление одного обычно исправляет и другое.

Читать на:
Выбор материализации Плохие incremental-модели Потолок параллелизма
Где обычно концентрируется время вычислений хранилища — не измерено на реальном проекте.

В отличие от кластера Spark, который вы сами провижините, проект dbt на Snowflake/BigQuery выставляет счёт за время вычислений хранилища — так что медленная модель не просто раздражает, она напрямую стоит денег. Это делает список диагностики короче и понятнее, чем может показаться.

Начните с elapsed_time против execution_time по каждой модели

Собственный run_results.json от dbt (записывается после каждого dbt run/build) уже содержит оба показателя: общее время выполнения запуска и время выполнения по каждой модели. Модель, чьё время выполнения мало относительно общего времени, — не проблема; проблема где-то выше по цепочке (очередь на хранилище, порядок зависимостей). Модель, чьё время выполнения реально доминирует в прогоне, — вот куда стоит смотреть в первую очередь.

Выбор материализации обычно — главный рычаг

Модель, материализованная как view и запрашиваемая многими нижестоящими моделями, фактически заново выполняет собственную логику при каждом обращении — превращая то, что должно быть разовой стоимостью, в повторяющуюся. Переключение часто запрашиваемого, дорогого преобразования на table или incremental часто резко снижает общие затраты на вычисления в хранилище, ценой некоторого объёма хранения и небольшой задержки актуальности.

Неправильно сделанные incremental-модели стоят дороже полных пересчётов

Incremental-модель с плохо выбранным unique_key или фильтром is_incremental(), который фактически не сужает сканирование (сканирует всю исходную таблицу при каждом «инкрементальном» прогоне), даёт всю сложность инкрементальной материализации без её экономии. Стоит явно проверить: действительно ли инкрементальный прогон сканирует меньше данных, чем полный пересчёт, по собственному профилю запроса хранилища?

У параллелизма (настройки threads в dbt) есть потолок

Больше потоков означает больше моделей, выполняющихся одновременно к хранилищу — до момента, когда все они начинают конкурировать за одни и те же слоты вычислений хранилища, и тогда больше потоков означает просто больше очередей, а не больше реальной пропускной способности. Этот потолок зависит от размера хранилища, так что значение, скопированное из настроек другого проекта, не обязательно подходит вашему.

Что opti-pipe читает из прогона dbt: общее время выполнения и время выполнения по каждой модели напрямую из run_results.json — никогда ваш SQL, имена моделей или пути к файлам — чтобы отметить, какие модели реально определяют стоимость прогона, тот же подход «смотреть на реальные цифры, а не гадать», что и в правилах для Spark выше.

Посмотрите, как это выглядит на вашем собственном пайплайне.

Загрузите реальный event log Spark, run_results.json от dbt или экспорт метрик Flink — и получите конкретные рекомендации, которые нужно одобрить, а не ещё одно эмпирическое правило.