Performance Tuning

Free Lesson

Advertisement

Performance Tuning

Performance Architecture

Architecture Diagram
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     PERFORMANCE OPTIMIZATION LAYERS                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                    OPTIMIZATION DIMENSIONS                           β”‚   β”‚
β”‚  β”‚                                                                     β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚   β”‚
β”‚  β”‚  β”‚  COMPILE     β”‚  β”‚  EXECUTE     β”‚  β”‚    MATERIALIZE           β”‚ β”‚   β”‚
β”‚  β”‚  β”‚              β”‚  β”‚              β”‚  β”‚                          β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ Jinja      β”‚  β”‚ β€’ SQL        β”‚  β”‚ β€’ Table                  β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ Parsing    β”‚  β”‚ β€’ Warehouse  β”‚  β”‚ β€’ View                   β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ Graph      β”‚  β”‚ β€’ Parallel   β”‚  β”‚ β€’ Incremental            β”‚ β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                              β”‚                                              β”‚
β”‚                              β–Ό                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                    OPTIMIZATION STRATEGIES                          β”‚   β”‚
β”‚  β”‚                                                                     β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚   β”‚
β”‚  β”‚  β”‚  CACHING     β”‚  β”‚  PARTITION   β”‚  β”‚    CLUSTERING            β”‚ β”‚   β”‚
β”‚  β”‚  β”‚              β”‚  β”‚              β”‚  β”‚                          β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ Result     β”‚  β”‚ β€’ Date       β”‚  β”‚ β€’ Query patterns         β”‚ β”‚   β”‚
β”‚  β”‚  β”‚   cache      β”‚  β”‚ β€’ Timestamp  β”‚  β”‚ β€’ Join keys              β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ Metadata   β”‚  β”‚ β€’ Integer    β”‚  β”‚ β€’ Filter columns         β”‚ β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Parallel Execution

Architecture Diagram
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     PARALLEL EXECUTION MODEL                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                    DAG-BASED PARALLELISM                             β”‚   β”‚
β”‚  β”‚                                                                     β”‚   β”‚
β”‚  β”‚  Level 0:  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚   β”‚
β”‚  β”‚            β”‚ stg_    β”‚  β”‚ stg_    β”‚  β”‚ stg_    β”‚                   β”‚   β”‚
β”‚  β”‚            β”‚ orders  β”‚  β”‚ custs   β”‚  β”‚ productsβ”‚                   β”‚   β”‚
β”‚  β”‚            β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜                   β”‚   β”‚
β”‚  β”‚                 β”‚            β”‚            β”‚                          β”‚   β”‚
β”‚  β”‚  Level 1:      β–Ό            β–Ό            β–Ό                          β”‚   β”‚
β”‚  β”‚            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚   β”‚
β”‚  β”‚            β”‚ int_    β”‚  β”‚ int_    β”‚  β”‚ int_    β”‚                   β”‚   β”‚
β”‚  β”‚            β”‚ orders  β”‚  β”‚ custs   β”‚  β”‚ productsβ”‚                   β”‚   β”‚
β”‚  β”‚            β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜                   β”‚   β”‚
β”‚  β”‚                 β”‚            β”‚            β”‚                          β”‚   β”‚
β”‚  β”‚  Level 2:      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚   β”‚
β”‚  β”‚                             β–Ό                                       β”‚   β”‚
β”‚  β”‚                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                   β”‚   β”‚
β”‚  β”‚                       β”‚ fct_    β”‚                                   β”‚   β”‚
β”‚  β”‚                       β”‚ orders  β”‚                                   β”‚   β”‚
β”‚  β”‚                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                   β”‚   β”‚
β”‚  β”‚                                                                     β”‚   β”‚
β”‚  β”‚  Execution:                                                         β”‚   β”‚
β”‚  β”‚  β”œβ”€β”€ Level 0: 3 models parallel (100% speedup)                     β”‚   β”‚
β”‚  β”‚  β”œβ”€β”€ Level 1: 3 models parallel (100% speedup)                     β”‚   β”‚
β”‚  β”‚  └── Level 2: 1 model (sequential)                                 β”‚   β”‚
β”‚  β”‚                                                                     β”‚   β”‚
β”‚  β”‚  Total: 7 models executed in 3 levels vs 7 sequential steps        β”‚   β”‚
β”‚  β”‚  Speedup: ~57% reduction in execution time                         β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Caching Strategy

Architecture Diagram
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     CACHING ARCHITECTURE                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                    CACHE LEVELS                                      β”‚   β”‚
β”‚  β”‚                                                                     β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚   β”‚
β”‚  β”‚  β”‚   L1: MEM    β”‚  β”‚   L2: DISK   β”‚  β”‚   L3: WAREHOUSE         β”‚ β”‚   β”‚
β”‚  β”‚  β”‚              β”‚  β”‚              β”‚  β”‚                          β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ In-memory  β”‚  β”‚ β€’ Local disk β”‚  β”‚ β€’ Query result           β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ Fastest    β”‚  β”‚ β€’ Fast       β”‚  β”‚ β€’ Persistent             β”‚ β”‚   β”‚
β”‚  β”‚  β”‚ β€’ Volatile   β”‚  β”‚ β€’ Persistent β”‚  β”‚ β€’ Shared                 β”‚ β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                              β”‚                                              β”‚
β”‚                              β–Ό                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                    CACHE HIT FLOW                                    β”‚   β”‚
β”‚  β”‚                                                                     β”‚   β”‚
β”‚  β”‚  Request β†’ L1 Cache? β†’ Hit? β†’ Return                                β”‚   β”‚
β”‚  β”‚              β”‚                                                       β”‚   β”‚
β”‚  β”‚              β–Ό No                                                    β”‚   β”‚
β”‚  β”‚          L2 Cache? β†’ Hit? β†’ Store in L1 β†’ Return                    β”‚   β”‚
β”‚  β”‚              β”‚                                                       β”‚   β”‚
β”‚  β”‚              β–Ό No                                                    β”‚   β”‚
β”‚  β”‚          L3 Cache? β†’ Hit? β†’ Store in L2/L1 β†’ Return                 β”‚   β”‚
β”‚  β”‚              β”‚                                                       β”‚   β”‚
β”‚  β”‚              β–Ό No                                                    β”‚   β”‚
β”‚  β”‚          Execute Query β†’ Store in all caches β†’ Return                β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Detailed Explanation

Performance tuning in dbt involves optimizing multiple layers: compilation, execution, and materialization.

Compilation Optimization

  1. Jinja Caching: Cache compiled templates
  2. Graph Optimization: Minimize dependency depth
  3. Incremental Parsing: Only recompile changed files
  4. Parallel Parsing: Parse files concurrently

Execution Optimization

  1. Thread Control: Adjust parallelism per model
  2. Batch Processing: Process data in optimal batch sizes
  3. Query Optimization: Use efficient SQL patterns
  4. Warehouse Sizing: Right-size compute resources

Materialization Optimization

  1. Incremental Models: Process only new/changed data
  2. Partitioning: Partition large tables for pruning
  3. Clustering: Cluster by frequently filtered columns
  4. Materialized Views: Use for frequently accessed aggregations

Caching Strategies

  1. Result Caching: Cache query results
  2. Metadata Caching: Cache schema information
  3. Compiled SQL Caching: Cache compiled SQL
  4. Package Caching: Cache installed packages

Monitoring Performance

Track key metrics:

  • Model build time
  • Test execution time
  • Query performance
  • Resource utilization

Code Examples

Thread Configuration

# dbt_project.yml
name: 'my_project'
version: '1.0.0'

# Global thread configuration
config-version: 2

# Model-specific thread overrides
models:
  my_project:
    staging:
      +threads: 4
    
    intermediate:
      +threads: 2
    
    marts:
      +threads: 8

# Profile-level threads
# profiles.yml
my_profile:
  target: dev
  outputs:
    dev:
      type: snowflake
      threads: 8

Optimized Incremental Model

-- models/marts/fct_events_optimized.sql
{{
    config(
        materialized='incremental',
        unique_key='event_id',
        incremental_strategy='merge',
        partition_by={
            "field": "event_date",
            "data_type": "date",
            "granularity": "day"
        },
        cluster_by=['user_id', 'event_type', 'event_timestamp'],
        post_hook=[
            "analyze table {{ this }} compute statistics for all columns"
        ]
    )
}}

with events as (
    select * from {{ ref('stg_events') }}
),

final as (
    select
        event_id,
        user_id,
        event_type,
        event_timestamp,
        cast(event_timestamp as date) as event_date,
        event_properties,
        current_timestamp() as updated_at
    from events
)

select * from final

{% if is_incremental() %}
where event_date >= date_sub(
    (select max(event_date) from {{ this }}),
    interval 3 day
)
{% endif %}

Partitioned Table Configuration

# models/marts/fct_orders.yml
version: 2

models:
  - name: fct_orders
    description: "Fact table for orders"
    
    config:
      materialized: incremental
      unique_key: order_id
      incremental_strategy: merge
      
      partition_by:
        field: order_date
        data_type: date
        granularity: day
        range:
          start: "2020-01-01"
          end: "2025-12-31"
          interval: 1
      
      cluster_by:
        - customer_id
        - order_status
        - product_category
      
      post_hook:
        - "analyze table {{ this }} compute statistics for all columns"
        - "grant select on {{ this }} to role analytics_reader"

Performance Monitoring

-- macros/monitoring/log_model_performance.sql
{% macro log_model_performance() %}
    {% if execute %}
        {% set start_time = modules.datetime.datetime.now() %}
        
        {{ return('') }}
        
        {% set end_time = modules.datetime.datetime.now() %}
        {% set duration = (end_time - start_time).total_seconds() %}
        
        insert into {{ target.schema }}.model_performance_log (
            model_name,
            execution_time,
            row_count,
            execution_date
        )
        values (
            '{{ this.name }}',
            {{ duration }},
            (select count(*) from {{ this }}),
            current_timestamp()
        )
    {% endif %}
{% endmacro %}

Optimized SQL Patterns

-- models/marts/fct_orders_optimized.sql
{{
    config(
        materialized='incremental',
        unique_key='order_id',
        incremental_strategy='merge',
        partition_by={
            "field": "order_date",
            "data_type": "date"
        },
        cluster_by=['customer_id']
    )
}}

-- Use CTEs for complex logic
with orders as (
    select * from {{ ref('stg_orders') }}
),

customers as (
    select * from {{ ref('dim_customers') }}
),

-- Use window functions efficiently
order_metrics as (
    select
        order_id,
        customer_id,
        order_date,
        amount,
        row_number() over (
            partition by customer_id 
            order by order_date desc
        ) as order_sequence,
        sum(amount) over (
            partition by customer_id
            order by order_date
            rows between unbounded preceding and current row
        ) as cumulative_amount
    from orders
),

final as (
    select
        order_id,
        customer_id,
        order_date,
        amount,
        order_sequence,
        cumulative_amount,
        current_timestamp() as updated_at
    from order_metrics
)

select * from final

{% if is_incremental() %}
where updated_at > (select max(updated_at) from {{ this }})
{% endif %}

Performance Metrics

MetricDescriptionTarget
Compile TimeTime to compile project<10s
Execution TimeTime to run all models<30min
Test TimeTime to run all tests<5min
Query TimeAverage query execution<10s
Cache Hit RatePercentage of cache hits>80%

Best Practices

  1. Use incremental models - Process only new/changed data
  2. Partition large tables - Enable partition pruning
  3. Cluster by query patterns - Optimize for common filters
  4. Adjust thread counts - Right-size parallelism
  5. Enable caching - Cache query results
  6. Monitor performance - Track key metrics
  7. Optimize SQL - Use efficient patterns
  8. Right-size warehouses - Match compute to workload

Advertisement

Need Expert dbt Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement