Cet article parle d’un pattern avancé d’optimisation des requêtes dans dbt : le “Dynamic Partition Pruning” (pruning dynamique des partitions), combiné à des macros et variables pour contrôler dynamiquement les filtres de partition.
🧠 C’est quoi le Dynamic Partition Pruning ?
C’est une optimisation du moteur SQL du data warehouse (comme BigQuery, Snowflake, Databricks…) qui permet de ne lire que les partitions utiles dans une table partitionnée, au moment de l’exécution de la requête (et non lors de la compilation dbt).
📌 Objectif : limiter le scan de données inutile, donc accélérer la requête et réduire le coût.
⚙️ Exemple classique sans pruning
SELECT * FROM ventes
WHERE date_vente >= '2024-06-01'
➡️ Ici, la valeur '2024-06-01'
est figée à la compilation
➡️ dbt ne peut pas adapter ce filtre dynamiquement en prod
✅ Solution : macro + variable à l’exécution
Tu écris une macro qui permet de déterminer dynamiquement les filtres de partitions, en fonction de variables passées à l’exécution, par exemple :
dbt run --vars '{"date_min": "2024-06-01"}'
Et dans ton modèle :
{% set date_min = var('date_min', '2024-01-01') %}
SELECT *
FROM ventes
WHERE date_vente >= '{{ date_min }}'
➡️ Tu utilises une variable modifiable dynamiquement à chaque dbt run
, ce qui :
- te permet de ne pas modifier le SQL
- te permet de contrôler la partition cible
- laisse le query optimizer du warehouse faire le pruning automatiquement
🧠 Pourquoi utiliser des macros pour centraliser cette logique ?
Imaginons que tu aies plusieurs modèles partitionnés, tu ne veux pas dupliquer cette logique.
Tu crées alors une macro réutilisable :
macros/filters/partition_filter.sql
{% macro partition_filter(field='date_vente', default='2024-01-01') %}
{% set v = var('date_min', default) %}
{{ field }} >= '{{ v }}'
{% endmacro %}
Et dans ton modèle :
SELECT *
FROM ventes
WHERE {{ partition_filter('date_vente', '2024-01-01') }}
✅ Avantages :
- 📦 logique de filtrage centralisée
- 🧪 plus facile à maintenir et tester
- 🔁 flexible à chaque exécution dbt
- ⚡️ compatible avec partition pruning du warehouse
🛠 Compatible avec quels entrepôts ?
Warehouse | Support du pruning | Notes |
---|---|---|
BigQuery | ✅ Oui | Basé sur partition column filters |
Snowflake | ✅ Oui | Automatique sur tables partitionnées par clustering |
Databricks | ✅ Très performant | Optimisé avec Delta Lake |
Redshift | ⚠️ Limité | Nécessite du sortkey + predicate pushdown |
✅ Avantages du pattern
Avantage | Détail |
---|---|
✅ Performance | Moins de partitions lues → requête plus rapide |
✅ Réduction de coûts | Scan de données réduit |
✅ Maintenance facilitée | La logique est centralisée en macro |
✅ Flexibilité | Tu peux modifier la plage de dates à la volée |
✅ Réutilisable | Plusieurs modèles peuvent appeler la même macro |
🧠 Résumé
Élément | Rôle |
---|---|
var('date_min') | Permet de passer dynamiquement un filtre |
partition_filter() (macro) | Génère la condition SQL de partition |
Query optimizer (du warehouse) | Utilise cette condition pour pruner les partitions non nécessaires |
dbt | Ne compile pas tout statiquement → laisse le moteur SQL optimiser dynamiquement |