# Оптимизация затрат в dbt

Требуется вход | Оплата по использованию

dbt предлагает способы оптимизации использования сборок моделей и затрат на хранилище данных.

### Рекомендации по оптимизации затрат с помощью dbt State

#### Используйте `lag_tolerance`, чтобы сократить количество ненужных запусков моделей

Вы можете сэкономить ещё больше времени и вычислительных ресурсов, определив, насколько устаревшими могут быть данные до того, как потребуется запустить модель. Мы добавили `lag_tolerance`, чтобы вы могли, например, задавать разные требования для среды разработки и производственной среды.

Например:

dbt\_project.yml

```yaml
models:
  +state:
    lag_tolerance: "{{ '4h' if target.name == 'prod' else '7d' }}"
```

В этом примере модели в целевом окружении `prod` пересобираются только тогда, когда возраст данных вышестоящих узлов превышает 4 часа. Во всех остальных средах модели ожидают 7 дней перед пересборкой.

Подробности см. в [справочнике по конфигурации `lag_tolerance`](https://docs.getdbt.tech/reference/resource-configs/lag-tolerance.md).

#### Используйте селекторы с `dbt build`, чтобы ограничить запуск вышестоящих узлов

В среде разработки используйте [селекторы](https://docs.getdbt.tech/reference/node-selection/yaml-selectors.md) с `dbt build`, чтобы ограничить количество запускаемых вышестоящих узлов. Для узлов, которые не выбраны, можно использовать [отложенное разрешение ссылок (defer)](https://docs.getdbt.tech/reference/node-selection/defer.md) вместо пересборки, что позволяет избежать дополнительной активности dbt State в соответствующих целевых окружениях. Автоматический выбор `state:modified` в среде разработки может появиться в одном из будущих выпусков.

#### Избегайте условных материализаций

Избегайте схем условной материализации, например использования `table` в производственной среде и `view` в среде разработки для одной и той же модели. Различия в материализациях между средами могут мешать dbt State правильно сопоставлять целевые окружения и снижать эффективность пропуска и клонирования моделей.

### Рекомендации по оптимизации количества успешно собранных моделей

Вы можете сократить затраты, связанные с количеством успешно собранных моделей, продолжая следовать рекомендуемым практикам. Комбинируйте приведённые ниже подходы в соответствии со своими потребностями. Если вы исключаете представления из запусков заданий по расписанию, настройте [задание слияния](#exclude-views-while-running-tests), чтобы развёртывать обновлённую логику представлений при обнаружении изменений.

#### Исключение представлений из задания dbt

Многие пользователи dbt используют представления, которые не всегда нужно пересобирать при каждом запуске задания. Для заданий, содержащих представления, которые *не* включают макросы, динамически генерирующие код (например, выражения case) на основе вышестоящих таблиц, и также *не* имеют тестов, можно выполнить следующие действия:

1. Откройте текущее задание развёртывания в производственной среде в dbt.
2. Добавьте в команду: `--exclude config.materialized:view`.
3. Сохраните изменения задания.

Если у вас есть представления, содержащие макросы с выражениями case на основе вышестоящих таблиц, их нужно запускать каждый раз, чтобы учитывать новые значения. Если вам по-прежнему необходимо тестировать представления при каждом запуске, следуйте рекомендациям из раздела [Исключение представлений с сохранением запуска тестов](#exclude-views-while-running-tests), чтобы создать собственный селектор.

#### Исключение представлений с сохранением запуска тестов

Запуск тестов для представлений при каждом запуске задания помогает поддерживать качество данных и избавляет от необходимости повторно запускать задания, завершившиеся с ошибкой. Чтобы исключить представления из запуска задания, но при этом выполнять тесты, создайте собственный [селектор](https://docs.getdbt.tech/reference/node-selection/yaml-selectors.md) для команды задания, выполнив следующие действия.

1. Откройте проект dbt в Studio IDE.

2. Добавьте файл с именем `selectors.yml` в корневую папку проекта.

3. Добавьте в файл следующий код:

   ```yaml
    selectors:
      - name: skip_views_but_test_views
        description: >
          A default selector that will exclude materializing views
          without skipping tests on views.
        default: true
        definition:
          union:
            - union: 
              - method: path
                value: "*"
              - exclude: 
                - method: config.materialized
                  value: view
            - method: resource_type
              value: test
   ```

4. Сохраните файл и зафиксируйте его в репозитории проекта.

5. Измените задания dbt, добавив команду (Версии dbt: v1.12 и новее) `dbt build --select selector:skip_views_but_test_views`.

#### Сборка только изменённых представлений

Если вы хотите, чтобы представления собирались при каждом изменении их логики, создайте задание слияния, которое запускается при слиянии кода в main:

1. Убедитесь, что в вашей среде [настроено задание CI](https://docs.getdbt.tech/docs/deploy/ci-jobs.md).
2. Создайте новое [задание развёртывания](https://docs.getdbt.tech/docs/deploy/deploy-jobs.md#create-and-schedule-jobs) и назовите его «Merge Job».
3. В поле **Environment** укажите свою среду CI. Подробности см. в разделе [Типы сред](https://docs.getdbt.tech/docs/deploy/deploy-environments.md#types-of-environments).
4. В поле **Commands** укажите: `dbt run -s state:modified+`. Выполнять `dbt build` в этом случае не требуется, поскольку задание CI уже использовалось и для запуска, и для тестирования кода, который только что был слит в main.
5. В разделе **Execution Settings** выберите производственное задание по умолчанию для сравнения изменений:
   * **Defer to a previous run state** — Выберите созданное задание «Merge Job», чтобы оно сравнивало состояния и определяло, что изменилось с момента последнего слияния.
6. Следуйте руководству [Настройка CI/CD с помощью собственных конвейеров](https://docs.getdbt.tech/guides/custom-cicd-pipelines.md), чтобы создать скрипт, который обращается к API dbt для запуска задания после слияния, или посмотрите это [видео](https://www.loom.com/share/e7035c61dbed47d2b9b36b5effd5ee78?sid=bcf4dd2e-b249-4e5d-b173-8ca204d9becb).

Задание слияния немедленно развёртывает изменения из PR в производственной среде и поддерживает соответствие производственных представлений вашей кодовой базе, сохраняя экономичность. Оцените, подходит ли такое изменение для вашего проекта dbt.

### Переработка неэффективных моделей

#### Вкладка Insights задания

Чтобы сократить расходы на хранилище данных, используйте вкладку **Insights** на странице **Job** для поиска моделей, сборка которых занимает больше всего времени. Диаграмма показывает среднее время выполнения каждой модели за последние 20 запусков; самые медленные модели — основные кандидаты на оптимизацию.

#### Вкладка Model Timing

Чтобы узнать, сколько времени занимает выполнение каждой модели в конкретном запуске, выберите этот запуск на странице **Run History** и откройте вкладку **Model Timing**.

Определив модели, которые можно оптимизировать, ознакомьтесь с дополнительными материалами, в которых описаны способы оптимизации вашей работы:

* [Создание масштабируемых и надёжных конвейеров данных с помощью dbt и BigQuery](https://services.google.com/fh/files/misc/dbt_bigquery_whitepaper.pdf)
* [Рекомендации по оптимизации развёртывания dbt и Snowflake](https://www.snowflake.com/wp-content/uploads/2021/10/Best-Practices-for-Optimizing-Your-dbt-and-Snowflake-Deployment.pdf)
* [Оптимизация моделей dbt в Databricks и устранение неполадок](https://docs.getdbt.tech/guides/optimize-dbt-models-on-databricks.md)

Ответы на распространённые вопросы о тарифных планах и оплате см. в разделе [Часто задаваемые вопросы об оплате](https://docs.getdbt.tech/docs/platform/billing-faqs.md).
