Postgres 설정

Postgres 설정

dbt-postgres 어댑터의 설정을 정리한 페이지예요. incremental materialization 전략, unlogged 테이블 같은 성능 최적화, 인덱스 구성, 그리고 materialized view 설정을 소개해요.

출처: dbt 공식 문서

본문

Incremental materialization 전략

dbt-postgres에서 다음 incremental materialization 전략을 지원해요.

  • append (unique_key가 정의되지 않았을 때 기본값)
  • merge
  • delete+insert (unique_key가 정의됐을 때 기본값)
  • microbatch

성능 최적화

Unlogged

"Unlogged" 테이블은 write-ahead 로그에 기록되지 않고 읽기 복제본에도 복제되지 않아 일반 테이블보다 상당히 빠를 수 있어요. 다만 일반 테이블보다 훨씬 덜 안전하기도 해요. 자세한 내용은 Postgres 문서를 참고해요.

my_table.sql

{{ config(materialized='table', unlogged=True) }}

select ...

dbt_project.yml

models:
  +unlogged: true

인덱스

Postgres는 약 1천만 행보다 작은 데이터셋에서는 꽤 잘 동작하지만, 데이터베이스 튜닝이 필요할 때도 있어요. 조인이나 where 절에 자주 쓰이는 컬럼에는 인덱스를 만드는 게 중요해요.

Table 모델, incremental 모델, 시드, 스냅샷, materialized view에는 indexes 목록을 정의할 수 있어요. 각 Postgres 인덱스는 세 가지 구성 요소를 가질 수 있어요.

  • columns (목록, 필수): 인덱스가 정의되는 하나 이상의 컬럼이에요.
  • unique (불리언, 선택): 인덱스를 고유(unique)로 선언할지 여부예요.
  • type (문자열, 선택): 지원되는 인덱스 유형(B-tree, Hash, GIN 등)이에요.

my_table.sql

{{ config(
    materialized = 'table',
    indexes=[
      {'columns': ['column_a'], 'type': 'hash'},
      {'columns': ['column_a', 'column_b'], 'unique': True},
    ]
)}}

select ...

리소스에 인덱스가 하나 이상 구성되면 dbt는 그 리소스의 materialization 일부로, 메인 create 문과 같은 트랜잭션 안에서 create index DDL 문을 실행해요. 인덱스 이름에는 고유성을 보장하고 다른 인덱스와 네임스페이스 충돌을 피하기 위해 그 속성과 현재 타임스탬프의 해시를 사용해요.

create index if not exists
"3695050e025a7173586579da5b27d275"
on "my_target_database"."my_target_schema"."indexed_model" 
using hash
(column_a);

create unique index if not exists
"1bf5f4a6b48d2fd1a9b0470f754c1b0d"
on "my_target_database"."my_target_schema"."indexed_model" 
(column_a, column_b);

여러 리소스에 대해 한 번에 인덱스를 구성할 수도 있어요.

dbt_project.yml

models:
  project_name:
    subdirectory:
      +indexes:
        - columns: ['column_a']
          type: hash

Materialized views

Postgres 어댑터는 다음 설정 파라미터와 함께 materialized views를 지원해요.

파라미터 타입 필수 기본값 변경 모니터링 지원
on_configuration_change <string> 아니요 apply n/a
indexes [{<dictionary>}] 아니요 none alter

프로젝트 YAML 파일

dbt_project.yml

models:
  <resource-path>:
    +materialized: materialized_view
    +on_configuration_change: apply | continue | fail
    +indexes:
      - columns: [<column-name>]
        unique: true | false
        type: hash | btree

프로퍼티 YAML 파일

models/properties.yml


models:
  - name: [<model-name>]
    config:
      materialized: materialized_view
      on_configuration_change: apply | continue | fail
      indexes:
        - columns: [<column-name>]
          unique: true | false
          type: hash | btree

SQL 파일 설정

models/<model_name>.sql

{{ config(
    materialized="materialized_view",
    on_configuration_change="apply" | "continue" | "fail",
    indexes=[
        {
            "columns": ["<column-name>"],
            "unique": true | false,
            "type": "hash" | "btree",
        }
    ]
) }}

indexes 파라미터는 위에서 설명한 테이블의 것과 동일해요. 테이블과 달리 dbt는 이 파라미터의 변경을 모니터링하고 materialized view를 드롭하지 않고 변경을 적용한다는 점이 주목할 만해요. 이는 인덱스의 DROP/CREATE로 이루어지며, materialized view에 대한 ALTER로 생각할 수 있어요.

이 파라미터에 대한 자세한 내용은 Postgres의 문서에서 확인해요.

더 알아보기 (Learn more)