Optimiser les performances des tables dynamiques¶
Cette rubrique couvre les techniques d’optimisation des performances des tables dynamiques, organisées en modifications et ajustements de la conception.
Avant d’optimiser une table dynamique, vous pouvez diagnostiquer la cause des actualisations lentes. Consultez Diagnostic des actualisations lentes pour un workflow étape par étape.
Pour plus d’informations sur les catégories de performances, consultez Décisions en matière de performances.
Modifications de la conception¶
Les modifications de la conception nécessitent de recréer une table dynamique, mais ont un impact plus important sur les performances.
Note
Nous vous recommandons de regrouper les modifications et de recréer des tables ensemble au lieu de procéder à des modifications incrémentielles.
Sélectionner un mode d’actualisation¶
Le mode d’actualisation que vous choisissez a un impact important sur les performances, car il détermine la quantité de données que Snowflake traite à chaque actualisation. Pour plus d’informations sur le fonctionnement de chaque mode, consultez Modes d’actualisation des tables dynamiques.
Important
Les tables dynamiques avec actualisation incrémentielle ne peuvent pas être inférieures à des tables dynamiques qui utilisent une actualisation complète.
Utilisez le processus de décision suivant pour sélectionner un mode d’actualisation :
Examinez votre requête par rapport à la liste de constructions de requêtes prises en charge. Tous les opérateurs de requêtes ne prennent pas en charge l’actualisation incrémentielle. Pour les opérateurs qui sont pris en charge, consultez Optimiser les requêtes pour l’actualisation incrémentielle pour comprendre comment ils affectent les performances.
Estimez votre volume de modifications, c’est-à-dire le pourcentage de vos données qui change entre les actualisations. L’actualisation incrémentielle, par exemple, fonctionne mieux lorsque moins de 5 % des données changent.
Évaluez la localité de vos données. Vérifiez si vos tables sources sont mises en cluster par les clés que vous prévoyez d’utiliser dans les clauses de jointure, GROUP BY ou PARTITION BY dans votre requête de table dynamique. Une faible localité réduit l’efficacité de l’actualisation incrémentielle. Pour améliorer la localité, consultez Améliorer la localité des données.
Choisissez un mode en fonction du tableau suivant :
Mode
Quand utiliser
Incrémentiel
Votre requête utilise des opérateurs pris en charge, moins de 5 % des données changent entre les actualisations, et vos tables sources présentent une bonne localité des données.
Note
L’actualisation incrémentielle peut toujours analyser les tables sources, et pas seulement les lignes qui ont été modifiées. Par exemple, une nouvelle ligne dans un côté d’une jointure doit correspondre à toutes les lignes de l’autre table. Même un petit nombre de changements peut déclencher un travail important.
Complet
Un pourcentage élevé de données change, votre requête utilise des opérateurs non pris en charge, ou vos données manquent de localité.
Automatique
Vous effectuez un prototypage ou des tests. Évitez AUTO en production, car son comportement peut changer selon les versions de Snowflake.
Lorsque vous créez une table dynamique, spécifiez le mode avec
REFRESH_MODE = INCREMENTALouREFRESH_MODE = FULLdans votre instruction CREATE DYNAMIC TABLE.
Pour vérifier le mode d’actualisation utilisé par une table dynamique, consultez Actualiser le mode.
Optimiser vos requêtes et votre pipeline¶
La structure de vos requêtes de tables dynamiques et de votre pipeline affecte directement les performances d’actualisation. Utilisez les directives suivantes pour réduire le travail lors de chaque actualisation.
Simplifier les requêtes individuelles¶
Utilisez des jointures internes à la place des jointures externes. Les jointures internes sont plus performantes avec une actualisation incrémentielle. Vérifiez l’intégrité référentielle de vos données sources afin d’éviter les jointures externes.
Évitez les opérations inutiles. Supprimez les clauses DISTINCT redondantes et les colonnes inutilisées. Excluez les grandes colonnes (comme les blobs JSON volumineux) qui ne sont pas fréquemment interrogées.
Supprimez efficacement les doublons. Utilisez des fonctions de classement au lieu de DISTINCT lorsque cela est possible.
Pour obtenir des conseils détaillés sur la manière dont des opérateurs SQL spécifiques affectent les performances de l’actualisation incrémentielle, consultez Optimiser les requêtes pour l’actualisation incrémentielle.
Note
Pour un exemple complet, consultez Tutoriel : Optimiser les performances des tables dynamiques pour les workflows SCD de type 1.
Répartition des transformations entre les tables dynamiques¶
Le fait de répartir les transformations complexes en plusieurs tables dynamiques facilite l’identification des obstacles et améliore le débogage. Avec les contraintes d’immuabilité, vous pouvez également utiliser différents modes d’actualisation pour différentes zones de préparation.
Ajoutez des filtres tôt. Appliquez les clauses
WHEREdans les tables dynamiques les plus proches de vos données sources afin que les tables en aval traitent moins de lignes.Pour éviter des opérations
DISTINCTrépétées dans les tables en aval, supprimez les lignes en double plus tôt dans votre pipeline.Réduisez le nombre d’opérations par table. Déplacez les jointures, les agrégations ou les fonctions de fenêtre dans des tables dynamiques intermédiaires au lieu de les combiner dans une seule requête.
Matérialisez les expressions composées (comme
DATE_TRUNC('minute', ts)) dans une table intermédiaire avant de les regrouper. Pour plus de détails, voir Optimiser les agrégations.
Note
La recherche des points de division optimaux nécessite des essais et des erreurs.
Envisagez de fractionner les opérations qui brassent les données sur différentes clés, comme GROUP BY, DISTINCT, les fonctions de fenêtre avec PARTITION BY et les jointures. Cela permet à chaque table dynamique de maintenir une meilleure localité des données pour son opération de clé. Pour obtenir des conseils spécifiques à l’opérateur, consultez Optimiser les requêtes pour l’actualisation incrémentielle.
L’exemple suivant montre comment diviser une requête complexe en tables dynamiques intermédiaires.
Requête initiale complexe :
CREATE DYNAMIC TABLE final_result
TARGET_LAG = '1 hour'
WAREHOUSE = my_warehouse
AS
SELECT ...
FROM large_table a
JOIN dimension_table b ON ...
JOIN another_table c ON ...
GROUP BY ...;
Fractionnez le pipeline complexe en ajoutant une table dynamique intermédiaire :
CREATE DYNAMIC TABLE intermediate_joined
TARGET_LAG = DOWNSTREAM
WAREHOUSE = my_warehouse
AS
SELECT ...
FROM large_table a
JOIN dimension_table b ON ...;
CREATE DYNAMIC TABLE final_result
TARGET_LAG = '1 hour'
WAREHOUSE = my_warehouse
AS
SELECT ...
FROM intermediate_joined
JOIN another_table c ON ...
GROUP BY ...;
Pour obtenir des informations détaillées et des exemples sur la manière dont les opérateurs affectent les performances, consultez Optimiser les requêtes pour l’actualisation incrémentielle.
Marquer les données historiques immuables¶
Utilisez la clause IMMUTABLE WHERE pour indiquer à Snowflake que certaines lignes ne changeront pas. Cela réduit la portée du travail lors de chaque actualisation.
Pour voir la syntaxe, les exemples et les conseils détaillés, consultez Utiliser les contraintes d’immuabilité.
Ajustements¶
Les ajustements ne nécessitent pas que vous recréiez des tables dynamiques. Vous pouvez procéder à des ajustements pendant l’exécution de votre pipeline.
Ajuster la configuration de votre entrepôt¶
L’entrepôt que vous spécifiez dans votre instruction CREATE DYNAMIC TABLE exécute toutes les actualisations de cette table. La taille et la configuration de l’entrepôt affectent directement la durée et le coût de l’actualisation.
Pour plus d’informations sur les entrepôts et les tables dynamiques, consultez Comprendre l’utilisation de l’entrepôt pour les tables dynamiques. Pour connaître les stratégies générales d’optimisation des performances des entrepôts, consultez Optimisation des performances des entrepôts.
Utiliser un entrepôt séparé pour l’initialisation¶
Les actualisations initiales traitent souvent beaucoup plus de données que les actualisations incrémentielles. Utilisez INITIALIZATION_WAREHOUSE pour exécuter des initialisations sur un entrepôt plus volumineux. Réservez un entrepôt plus petit et plus rentable pour des actualisations régulières :
CREATE DYNAMIC TABLE my_dynamic_table
TARGET_LAG = 'DOWNSTREAM'
WAREHOUSE = 'XS_WAREHOUSE'
INITIALIZATION_WAREHOUSE = '4XL_WAREHOUSE'
AS <query>;
Pour ajouter ou modifier l’entrepôt d’initialisation d’une table dynamique existante, procédez comme suit :
ALTER DYNAMIC TABLE my_dynamic_table SET INITIALIZATION_WAREHOUSE = '4XL_WAREHOUSE';
Pour supprimer l’entrepôt d’initialisation et utiliser l’entrepôt principal pour toutes les actualisations, procédez comme suit :
ALTER DYNAMIC TABLE my_dynamic_table UNSET INITIALIZATION_WAREHOUSE;
Pour voir la configuration de l’entrepôt, utilisez SHOW DYNAMIC TABLES ou vérifiez la fonction de table DYNAMIC_TABLE_REFRESH_HISTORY.
Redimensionner si nécessaire¶
Pour équilibrer les coûts et les performances, choisissez une taille d’entrepôt qui empêche les octets de se déverser, mais qui ne dépasse pas ce que votre charge de travail peut utiliser en parallèle. Lorsque des actualisations plus rapides sont essentielles, augmentez la taille légèrement au-delà du point optimal en matière de coût.
Considérations relatives à l’actualisation des tables dynamiques :
Octets déversés : Lorsque l’historique des requêtes indique que des octets se sont déversés sur le stockage local ou le stockage distant, ’”entrepôt a épuisé la mémoire lors de l’actualisation. Un entrepôt plus grand fournit plus de mémoire pour éviter les déversements. Pour plus de détails, voir Requêtes trop volumineuses pour la mémoire.
Actualisation initiale lente : Lorsque l’actualisation initiale est lente, envisagez de définir INITIALIZATION_WAREHOUSE pour la création initiale, ou redimensionnez temporairement l’entrepôt, puis redimensionnez-le après la création de la table.
Parallélisme saturé : Au-delà d’un certain point, le parallélisme supplémentaire fournit des rendements décroissants. Le fait de doubler la taille de l’entrepôt peut doubler les coûts sans réduire de moitié la durée d’exécution. Pour vérifier comment votre actualisation utilise le parallélisme, examinez le profil de requête.
Pour redimensionner un entrepôt, consultez Augmentation de la taille des entrepôts.
Pour connaître les considérations relatives aux coûts, consultez Utilisation du crédit d’entrepôt virtuel et Utilisation d’entrepôts.
Gérer les actualisations simultanées avec les entrepôts multi-clusters¶
Si plusieurs tables dynamiques partagent un entrepôt et actualisent fréquemment la file d’attente, envisagez d’utiliser un entrepôt multi-clusters. Les entrepôts multi-clusters ajoutent automatiquement des clusters lorsque les requêtes sont mises en file d’attente et les suppriment lorsque la demande diminue. Cela améliore la latence d’actualisation pendant les périodes de forte activité sans avoir à payer pour la capacité inutilisée pendant les périodes creuses.
Pour obtenir des conseils sur l’identification et la réduction des files d’attente, consultez Réduction des files d’attente.
Les entrepôts multi-clusters nécessitent Enterprise Edition ou une version supérieure. Pour connaître les considérations relatives aux coûts, consultez Définition de la politique de mise à l’échelle d’un entrepôt multi-clusters.
Identifier la latence cible appropriée¶
La latence cible contrôle la fréquence d’actualisation de votre table dynamique. Une latence cible plus courte signifie des données plus récentes, mais des actualisations plus fréquentes et un coût de calcul plus élevé. Pour plus d’informations sur le fonctionnement de la latence cible, consultez Comprendre la latence cible des tables dynamiques.
Utilisez les recommandations suivantes pour optimiser la latence cible de votre charge de travail :
Utilisez DOWNSTREAM pour les tables intermédiaires qui n’ont pas besoin de garanties d’actualisation indépendantes. Ces tables ne sont actualisées que lorsque les tables en aval en ont besoin.
Consultez l’historique d’actualisation pour trouver la latence adéquate : Utilisez DYNAMIC_TABLE_REFRESH_HISTORY ou l’Snowsight pour analyser les durées d’actualisation et les actualisations ignorées. Définissez une latence cible légèrement supérieure à votre durée d’actualisation habituelle.
Modifier la latence cible¶
ALTER DYNAMIC TABLE my_dynamic_table SET TARGET_LAG = '1 hour';
Pour définir une table dynamique de sorte qu’elle soit actualisée en fonction de la demande en aval, procédez comme suit :
ALTER DYNAMIC TABLE my_dynamic_table SET TARGET_LAG = DOWNSTREAM;
Améliorer la localité des données¶
La localité décrit la proximité avec laquelle Snowflake stocke les lignes qui partagent les mêmes valeurs de clé. Lorsque les lignes avec des clés correspondantes couvrent moins de micro-partitions (bonne localité), les actualisations incrémentielles analysent moins de données. Lorsque les clés correspondantes couvrent de nombreuses micro-partitions (localité insuffisante), l’actualisation incrémentielle peut prendre plus de temps que l’actualisation complète.
Pour plus d’informations sur la manière dont Snowflake stocke les données, consultez Micro-partitions et clustering de données.
Cluster de tables sources¶
Le moyen le plus efficace d’améliorer la localité est de regrouper vos tables sources en fonction des clés utilisées dans votre requête de table dynamique (clés JOIN, GROUP BY ou PARTITION BY) :
ALTER TABLE my_source_table CLUSTER BY (join_key_column);
Lorsque vous joignez plusieurs colonnes et que vous ne pouvez pas toutes les clusteriser :
Priorisez le clustering des tables plus volumineuses en fonction des clés les plus sélectives.
Envisagez de créer des copies séparées des mêmes données clusterisées en fonction de différentes clés pour les utiliser dans différentes tables dynamiques.
Pour plus d’informations, voir Clés de clustering et tables en cluster. Pour activer le reclustering automatique, consultez Clustering automatique.
Facteurs qui affectent la localité¶
Au-delà du clustering de la table source, deux autres facteurs affectent la localité. Ceux-ci dépendent de vos modèles de données et sont plus difficiles à modifier directement :
Comment les nouvelles données s’alignent sur les clés de partition : L’actualisation incrémentielle est plus rapide lorsque les nouvelles lignes n’affectent qu’une petite partie de la table. Cela dépend de vos modèles d’ingestion de données, et non de la structure de vos requêtes.
Par exemple, les données de séries temporelles regroupées par heure présentent une bonne localité, car de nouvelles lignes partagent des horodatages récents. Les données regroupées par une colonne dont les valeurs sont réparties sur l’ensemble de la table présentent une faible localité.
Comment les changements s’alignent sur le clustering des tables dynamiques : Lorsque Snowflake applique des mises à jour ou des suppressions à une table dynamique, il doit localiser les lignes affectées. Cela est plus rapide lorsque les lignes modifiées sont stockées proches les unes des autres.
Par exemple, les mises à jour des lignes récentes fonctionnent bien lorsque la table dynamique est naturellement ordonnée en fonction du temps. Les mises à jour réparties sur l’ensemble de la table sont plus lentes. Ce facteur dépend de vos modèles de charge de travail, y compris des lignes qui changent et de la fréquence à laquelle elles changent.
Lorsque vous constatez une faible localité en raison de ces facteurs, demandez-vous si vous pouvez ajuster votre modèle de données ou vos modèles d’ingestion en amont.