

 Amazon Redshift ne prendra plus en charge la création de nouveaux Python à UDFs partir du patch 198. UDFs Le Python existant continuera de fonctionner jusqu'au 30 juin 2026. Pour plus d’informations, consultez le [ billet de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Analyse et amélioration des requêtes
<a name="c-query-tuning"></a>

La récupération d’informations à partir d’un entrepôt des données Amazon Redshift implique l’exécution de requêtes complexes sur des quantités de données extrêmement importantes, ce qui peut prendre beaucoup de temps à traiter. Pour être sûr de traiter les requêtes le plus rapidement possible, il existe un certain nombre d’outils que vous pouvez utiliser pour identifier les problèmes de performances potentiels.

**Topics**
+ [Flux de travail d’analyse des requêtes](c-query-analysis-process.md)
+ [Révision des alertes de requêtes](c-reviewing-query-alerts.md)
+ [Analyse du plan de requête](c-analyzing-the-query-plan.md)
+ [Analyse du résumé de la requête](c-analyzing-the-query-summary.md)
+ [Amélioration des performances des requêtes](query-performance-improvement-opportunities.md)
+ [Requêtes de diagnostics pour l’ajustement des requêtes](diagnostic-queries-for-query-tuning.md)

# Flux de travail d’analyse des requêtes
<a name="c-query-analysis-process"></a>

Si une requête est plus longue à traiter que prévu, utilisez les étapes suivantes pour identifier et corriger les problèmes susceptibles d’affecter négativement les performances de la requête. Si vous ne savez pas quelles requêtes de votre système peuvent voir leurs performances ajustées, commencez par exécuter la requête diagnostique dans [Identification des requêtes particulièrement indiquées pour un ajustement](identify-queries-that-are-top-candidates-for-tuning.md).

1. Assurez-vous que vos tables sont conçues conformément aux bonnes pratiques. Pour plus d’informations, consultez [Bonnes pratiques Amazon Redshift pour la conception de tables](c_designing-tables-best-practices.md).

1. Vérifiez si vous pouvez supprimer ou archiver des données superflues dans vos tables. Par exemple, supposons que vos requêtes ciblent toujours les six derniers mois de données, mais que vous avez les 18 derniers mois dans vos tables. Dans ce cas, vous pouvez supprimer ou archiver les données plus anciennes afin de réduire le nombre d’enregistrements devant être analysés et distribués.

1. Exécutez la commande [VACUUM](r_VACUUM_command.md) sur les tables de la requête pour récupérer de l’espace et trier à nouveau les lignes. L’exécution de VACUUM est utile si la région non triée est volumineuse et que la requête utilise la clé de tri dans une jointure ou dans le prédicat.

1. Exécutez la commande [ANALYSE](r_ANALYZE.md) sur les tables de la requête pour vous assurer que les statistiques sont à jour. L’exécution de ANALYZE est utile si l’une des tables de la requête a considérablement changé de taille récemment. Si l’exécution d’une commande ANALYZE complète prend trop de temps, exécutez ANALYZE sur une seule colonne pour réduire le temps de traitement. Cette approche mettra toujours à jour les statistiques de taille de la table, laquelle taille est un facteur important dans la planification de la requête.

1. Assurez-vous que votre requête a été exécutée une fois pour chaque type de client (en fonction du type de protocole de connexion utilisé par le client), afin que la requête soit mise à jour et en cache. Cette approche accélère les exécutions suivantes de la requête. Pour plus d’informations, consultez [Facteurs affectant la performance des requêtes](c-query-performance.md).

1. Vérifiez la table [STL\$1ALERT\$1EVENT\$1LOG](r_STL_ALERT_EVENT_LOG.md) afin d’identifier et de corriger les éventuels problèmes avec votre requête. Pour plus d’informations, consultez [Révision des alertes de requêtes](c-reviewing-query-alerts.md).

1. Exécutez la commande [EXPLAIN](r_EXPLAIN.md) pour obtenir le plan de requête et l’utiliser afin d’optimiser la requête. Pour plus d’informations, consultez [Analyse du plan de requête](c-analyzing-the-query-plan.md).

1. Utilisez les vues [SVL\$1QUERY\$1SUMMARY](r_SVL_QUERY_SUMMARY.md) et [SVL\$1QUERY\$1REPORT](r_SVL_QUERY_REPORT.md) pour obtenir des informations récapitulatives et les utiliser afin d’optimiser la requête. Pour plus d’informations, consultez [Analyse du résumé de la requête](c-analyzing-the-query-summary.md).

Parfois, une requête devant s’exécuter rapidement est contrainte d’attendre qu’une autre requête plus longue à s’exécuter se termine. Dans ce cas, vous pouvez ne rien avoir à améliorer dans la requête elle-même, mais vous pouvez améliorer les performances globales du système en créant et en utilisant des files d’attente de requête adaptées à chaque type de requête. Pour connaître les temps d’attente des files d’attente pour vos requêtes, consultez [Vérification des temps d’attente des requêtes dans les files d’attente](review-queue-wait-times-for-queries.md). Pour plus d’informations sur la configuration des files d’attente de requête, consultez [Gestion de la charge de travail](cm-c-implementing-workload-management.md).

# Révision des alertes de requêtes
<a name="c-reviewing-query-alerts"></a>

Pour utiliser la table système [STL\$1ALERT\$1EVENT\$1LOG](r_STL_ALERT_EVENT_LOG.md) afin d’identifier et de corriger d’éventuels problèmes de performances avec votre requête, procédez comme suit :

1. Exécutez la commande suivante pour déterminer l’ID de votre requête :

   ```
   select query, elapsed, substring
   from svl_qlog
   order by query
   desc limit 5;
   ```

   Examinez le texte de la requête tronquée dans le champ `substring` pour déterminer quelle valeur de `query` sélectionner. Si vous avez exécuté la requête plusieurs fois, utilisez la valeur de `query` de la ligne avec la valeur de `elapsed` inférieure. Il s’agit de la ligne de la version compilée. Si vous avez exécuté un grand nombre de requêtes, vous pouvez augmenter la valeur utilisée par la clause LIMIT utilisée pour vous assurer que votre requête est incluse.

1. Sélectionnez des lignes dans STL\$1ALERT\$1EVENT\$1LOG pour votre requête :

   ```
   Select * from stl_alert_event_log where query = MyQueryID;               
   ```  
![\[Un exemple de résultat de la requête STL_ALERT_EVENT_LOG.\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/images/stl_alert_event_log_results.png)

1. Evaluez les résultats de votre requête. Utilisez le tableau suivant pour rechercher des solutions possibles aux problèmes que vous avez identifiés.
**Note**  
Toutes les requêtes ne contiennent pas des lignes dans STL\$1ALERT\$1EVENT\$1LOG, seules celles ayant des problèmes identifiés.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/c-reviewing-query-alerts.html)

# Analyse du plan de requête
<a name="c-analyzing-the-query-plan"></a>

Exécutez la commande [EXPLAIN](r_EXPLAIN.md) pour obtenir un plan de requête.

Avant d’analyser le plan de requête, vous devez savoir comment le lire. Si vous ne savez pas lire un plan de requête, nous vous recommandons de lire [Création et interprétation d’un plan de requêtes](c-the-query-plan.md) avant de poursuivre.

Pour analyser les données fournies par le plan de requête, procédez comme suit :

1. Identifiez les étapes ayant le coût le plus élevé. Consacrez-vous à les optimiser lorsque vous effectuez les dernières étapes.

1. Observez les types de jointure :
   + **Boucle imbriquée** : ces jointures se produisent généralement parce qu’une condition de jointure a été omise. Pour connaître les solutions recommandées, consultez [Boucle imbriquée](query-performance-improvement-opportunities.md#nested-loop).
   + **Hachage et Joindre par hachage** : les jointures par hachage sont utilisées pour joindre des tables dans lesquelles les colonnes de jointure ne sont pas des clés de distribution, ni des clés de tri. Pour connaître les solutions recommandées, consultez [Joindre par hachage](query-performance-improvement-opportunities.md#hash-join).
   + **Joindre par fusion** : aucune modification n’est nécessaire.

1. Notez quelle table est utilisée pour la jointure interne et quelle table est utilisée pour la jointure externe. Le moteur de requête choisit généralement la plus petite table pour la jointure interne et la plus grande table pour la jointure externe. Si ce choix ne se fait pas, vos statistiques ne sont vraisemblablement pas à jour. Pour connaître les solutions recommandées, consultez [Statistiques de table manquantes ou obsolètes](query-performance-improvement-opportunities.md#table-statistics-missing-or-out-of-date).

1. Vérifiez s’il existe des opérations de tri onéreuses. Si c’est le cas, consultez [Lignes non triées ou mal triées](query-performance-improvement-opportunities.md#unsorted-or-mis-sorted-rows) pour connaître les solutions recommandées.

1. Recherchez les opérateurs de diffusion suivants là où il y a des opérations onéreuses :
   + **DS\$1BCAST\$1INNER** : indique que la table est diffusée à tous les nœuds de calcul. Ceci convient pour une petite table, mais n’est pas idéal pour une table de taille plus importante.
   + **DS\$1DIST\$1ALL\$1INNER** : indique que l’ensemble de la charge de travail est placé sur une seule tranche.
   + **DS\$1DIST\$1BOTH** : indique une redistribution intensive.

   Pour connaître les solutions recommandées pour ces situations, consultez [Distribution des données sous-optimales](query-performance-improvement-opportunities.md#suboptimal-data-distribution).

# Analyse du résumé de la requête
<a name="c-analyzing-the-query-summary"></a>

Pour obtenir des statistiques et des étapes d’exécution plus détaillées que dans le plan de requête généré par [EXPLAIN](r_EXPLAIN.md), utilisez les vues système [SVL\$1QUERY\$1SUMMARY](r_SVL_QUERY_SUMMARY.md) et [SVL\$1QUERY\$1REPORT](r_SVL_QUERY_REPORT.md).

SVL\$1QUERY\$1SUMMARY fournit des statistiques de requête par flux. Vous pouvez utiliser les informations fournies pour identifier les problèmes posés par les étapes onéreuses, de longue durée et qui écrivent sur le disque. 

La vue système SVL\$1QUERY\$1REPORT vous permet de consulter des informations similaires à celles de SVL\$1QUERY\$1SUMMARY, uniquement par tranche de nœuds de calcul, et non par flux. Vous pouvez utiliser les informations au niveau de la tranche pour identifier la distribution inégale de données dans le cluster (également appelée asymétrie de la distribution de données), qui force certains nœuds à travailler davantage que d’autres et affecte les performances des requêtes.

**Topics**
+ [Utilisation de la vue SVL\$1QUERY\$1SUMMARY](using-SVL-Query-Summary.md)
+ [Utilisation de la vue SVL\$1QUERY\$1REPORT](using-SVL-Query-Report.md)
+ [Mappage du plan de requête au résumé de la requête](query-plan-summary-map.md)

# Utilisation de la vue SVL\$1QUERY\$1SUMMARY
<a name="using-SVL-Query-Summary"></a>

Pour analyser les informations récapitulatives sur la requête par flux à l’aide de [SVL\$1QUERY\$1SUMMARY](r_SVL_QUERY_SUMMARY.md), procédez comme suit :

1. Exécutez la requête suivante pour déterminer l’ID de votre requête :

   ```
   select query, elapsed, substring
   from svl_qlog
   order by query
   desc limit 5;
   ```

   Examinez le texte de la requête tronquée dans le champ `substring` pour déterminer quelle valeur de `query` représente votre requête. Si vous avez exécuté la requête plusieurs fois, utilisez la valeur de `query` de la ligne avec la valeur de `elapsed` inférieure. Il s’agit de la ligne de la version compilée. Si vous avez exécuté un grand nombre de requêtes, vous pouvez augmenter la valeur utilisée par la clause LIMIT utilisée pour vous assurer que votre requête est incluse.

1. Sélectionnez les lignes de SVL\$1QUERY\$1SUMMARY pour votre requête. Ordonnez les résultats par flux, par segment et par étape :

   ```
   select * from svl_query_summary where query = MyQueryID order by stm, seg, step;
   ```

   Voici un exemple de résultat.  
![\[Exemple de résultat pour les lignes dans SVL_QUERY_SUMMARY correspondant à une requête donnée.\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/images/svl_query_summary_results.png)

1. Mappe les étapes aux opérations du plan de requête à l’aide des informations de [Mappage du plan de requête au résumé de la requête](query-plan-summary-map.md). Elles doivent avoir à peu près les mêmes valeurs pour les lignes et les octets (lignes \$1 largeur dans le plan de requête). Si ce n’est pas le cas, consultez [Statistiques de table manquantes ou obsolètes](query-performance-improvement-opportunities.md#table-statistics-missing-or-out-of-date) pour connaître les solutions recommandées.

1. Vérifiez si le champ `is_diskbased` a une valeur de `t` (true) pour n’importe quelle étape. Les hachages, les agrégats et les tris sont les opérateurs susceptibles d’écrire des données sur le disque si le système ne dispose pas de suffisamment de mémoire allouée pour le traitement des requêtes.

   Si `is_diskbased` a la valeur true, consultez [Mémoire insuffisante allouée à la requête](query-performance-improvement-opportunities.md#insufficient-memory-allocated-to-the-query) pour connaître les solutions recommandées.

1. Passez en revue les valeurs des `label` champs et vérifiez s'il existe une AGG-DIST-AGG séquence quelconque dans les étapes. Sa présence indique une agrégation en deux étapes, ce qui est onéreux. Pour résoudre ce problème, modifiez la clause GROUP BY pour utiliser la clé de distribution (la première clé, s’il y en a plusieurs).

1. Vérifiez la valeur de `maxtime` de chaque segment (identique à toutes les étapes du segment). Identifiez le segment ayant la valeur de `maxtime` la plus élevée et vérifiez les étapes de ce segment pour les opérateurs suivants.
**Note**  
Une valeur de `maxtime` élevée n’indique pas nécessairement de problème avec le segment. Malgré une valeur élevée, le temps de traitement du segment pourrait ne pas avoir été long. Tous les segments d’un flux sont chronométrés ensemble. Toutefois, certains segments en aval ne sont peut-être pas en mesure de s’exécuter tant qu’ils n’obtiennent pas de données de ceux situés en amont. Cela peut donner l’impression qu’ils ont pris beaucoup de temps, car leur valeur `maxtime` inclura leur temps d’attente et leur temps de traitement. 
   + **BCAST ou DIST** : dans ces cas, la valeur de `maxtime` élevée peut être le résultat d’une redistribution d’un grand nombre de lignes. Pour connaître les solutions recommandées, consultez [Distribution des données sous-optimales](query-performance-improvement-opportunities.md#suboptimal-data-distribution).
   + **HJOIN (jointure par hachage)** : si l’étape en question a une valeur très élevée dans le champ `rows` par rapport à la valeur de `rows` dans l’étape RETURN finale dans la requête, consultez [Joindre par hachage](query-performance-improvement-opportunities.md#hash-join) pour connaître les solutions recommandées.
   + **SCAN/SORT** : recherchez une séquence d’étapes SCAN, SORT, SCAN, MERGE juste avant une étape de jointure. Ce modèle indique que des données non triées sont analysées, triées, puis fusionnées avec la région triée de la table.

     Vérifiez si la valeur des lignes de l’étape SCAN est très élevée par rapport à la valeur des lignes de l’étape RETURN finale dans la requête. Ce modèle indique que le moteur d’exécution analyse des lignes qui sont ignorées par la suite, ce qui est inefficace. Pour connaître les solutions recommandées, consultez [Prédicat pas assez restrictif](query-performance-improvement-opportunities.md#insufficiently-restrictive-predicate). 

     Si la valeur `maxtime` de l’étape SCAN est élevée, consultez [Clause WHERE sous-optimale](query-performance-improvement-opportunities.md#suboptimal-WHERE-clause) pour connaître les solutions recommandées.

     Si la valeur `rows` de l’étape SORT n’est pas égale à zéro, consultez [Lignes non triées ou mal triées](query-performance-improvement-opportunities.md#unsorted-or-mis-sorted-rows) pour connaître les solutions recommandées.

1. Vérifiez les valeurs `rows` et `bytes` des étapes 5 à 10 précédant l’étape RETURN finale pour savoir quelle est la quantité de données renvoyée au client. Ce processus peut être complexe.

   Par exemple, dans l’exemple de requête récapitulative suivant, la troisième étape PROJECT fournit une valeur de `rows`, mais pas une valeur de `bytes`. Les étapes précédentes avec la même valeur de `rows` vous permettront de trouver l’étape SCAN qui fournit des informations sur les lignes et les octets :

    Voici un exemple de résultat.   
![\[Une ligne des résultats de la requête récapitulative correspond à une étape SCAN avec des informations à la fois sur les lignes et sur les octets.\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/images/rows_and_bytes.png)

   Si vous renvoyez un volume inhabituellement élevé de données, consultez [Ensemble de résultats très volumineux](query-performance-improvement-opportunities.md#very-large-result-set) pour connaître les solutions recommandées.

1. Vérifiez si la valeur de `bytes` est élevée par rapport à la valeur de `rows` pour n’importe quelle étape, par rapport aux autres étapes. Ce modèle peut indiquer que vous sélectionnez un grand nombre de colonnes. Pour connaître les solutions recommandées, consultez [Longue liste SELECT](query-performance-improvement-opportunities.md#large-SELECT-list).

# Utilisation de la vue SVL\$1QUERY\$1REPORT
<a name="using-SVL-Query-Report"></a>

Pour analyser les informations récapitulatives sur la requête par tranche à l’aide de [SVL\$1QUERY\$1REPORT](r_SVL_QUERY_REPORT.md), procédez comme suit :

1. Exécutez la commande suivante pour déterminer l’ID de votre requête :

   ```
   select query, elapsed, substring
   from svl_qlog
   order by query
   desc limit 5;
   ```

   Examinez le texte de la requête tronquée dans le champ `substring` pour déterminer quelle valeur de `query` représente votre requête. Si vous avez exécuté la requête plusieurs fois, utilisez la valeur de `query` de la ligne avec la valeur de `elapsed` inférieure. Il s’agit de la ligne de la version compilée. Si vous avez exécuté un grand nombre de requêtes, vous pouvez augmenter la valeur utilisée par la clause LIMIT utilisée pour vous assurer que votre requête est incluse.

1. Sélectionner des lignes dans SVL\$1QUERY\$1REPORT pour votre requête. Ordonnez les résultats par segment, par étape, par elapsed\$1time et par lignes :

   ```
   select * from svl_query_report where query = MyQueryID order by segment, step, elapsed_time, rows;
   ```

1. Pour chaque étape, vérifiez que toutes les tranches traitent à peut près le même nombre de lignes :  
![\[Liste des tranches de données utilisées pour exécuter une requête. Chaque tranche traite approximativement le même nombre de lignes.\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/images/SVL_QUERY_REPORT_rows.png)

   Vérifiez également que toutes les tranches prennent à peu près autant de temps :  
![\[Liste des tranches de données utilisées pour exécuter une requête. Chaque tranche prend approximativement le même temps.\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/images/SVL_QUERY_REPORT_elapsed_time.png)

   Si ces valeurs sont très différences, cela peut révéler une asymétrie de la distribution des données due à un style de distribution sous-optimal pour cette requête particulière. Pour connaître les solutions recommandées, consultez [Distribution des données sous-optimales](query-performance-improvement-opportunities.md#suboptimal-data-distribution).

# Mappage du plan de requête au résumé de la requête
<a name="query-plan-summary-map"></a>

Lors de l’analyse de la requête récapitulative, vous pouvez obtenir plus de détails en mappant les opérations entre le plan de la requête et les étapes (identifiées par les valeurs du champ d’étiquette) dans le résumé de la requête. La table suivante fait correspondre les opérations du plan de requête aux étapes de la requête récapitulative.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/query-plan-summary-map.html)

# Amélioration des performances des requêtes
<a name="query-performance-improvement-opportunities"></a>

Voici quelques problèmes courants qui affectent les performances des requêtes Amazon Redshift, avec des instructions et des manières de les diagnostiquer et de les résoudre.

**Topics**
+ [Statistiques de table manquantes ou obsolètes](#table-statistics-missing-or-out-of-date)
+ [Boucle imbriquée](#nested-loop)
+ [Joindre par hachage](#hash-join)
+ [Lignes fantômes ou non validées](#ghost-rows-or-uncommitted-rows)
+ [Lignes non triées ou mal triées](#unsorted-or-mis-sorted-rows)
+ [Distribution des données sous-optimales](#suboptimal-data-distribution)
+ [Mémoire insuffisante allouée à la requête](#insufficient-memory-allocated-to-the-query)
+ [Clause WHERE sous-optimale](#suboptimal-WHERE-clause)
+ [Prédicat pas assez restrictif](#insufficiently-restrictive-predicate)
+ [Ensemble de résultats très volumineux](#very-large-result-set)
+ [Longue liste SELECT](#large-SELECT-list)

## Statistiques de table manquantes ou obsolètes
<a name="table-statistics-missing-or-out-of-date"></a>

Si des statistiques de la table sont manquantes ou obsolètes, ce qui suit peut s’afficher :
+ Un message d’avertissement dans les résultats de la commande EXPLAIN.
+ Un événement d’alerte de statistiques manquantes dans STL\$1ALERT\$1EVENT\$1LOG. Pour plus d’informations, consultez [Révision des alertes de requêtes](c-reviewing-query-alerts.md).

Pour résoudre ce problème, exécutez [ANALYSE](r_ANALYZE.md).

## Boucle imbriquée
<a name="nested-loop"></a>

Si une boucle imbriquée est présente, un événement d’alerte de boucle imbriquée peut s’afficher dans STL\$1ALERT\$1EVENT\$1LOG. Vous pouvez également identifier ce type d’événement en exécutant la requête de la section [Identification des requêtes avec des boucles imbriquées](identify-queries-with-nested-loops.md). Pour plus d’informations, consultez [Révision des alertes de requêtes](c-reviewing-query-alerts.md).

Pour résoudre ce problème, vérifiez s’il existe des jointures croisées dans votre requête et supprimez-les si possible. Les jointures croisées sont des jointures sans condition de jointure qui entraînent le produit cartésien de deux tables. Elles sont généralement exécutées en tant que jointures de boucle imbriquée, qui sont les types de jointures les plus lents possibles.

## Joindre par hachage
<a name="hash-join"></a>

Si une jointure par hachage est présente, les éléments suivants peuvent s’afficher :
+ Des opérations de hachage et de jointure par hachage dans le plan de la requête. Pour plus d’informations, consultez [Analyse du plan de requête](c-analyzing-the-query-plan.md).
+ Une étape HJOIN dans le segment avec la valeur maxtime la plus élevée dans SVL\$1QUERY\$1SUMMARY. Pour plus d’informations, consultez [Utilisation de la vue SVL\$1QUERY\$1SUMMARY](using-SVL-Query-Summary.md).

Pour résoudre ce problème, vous pouvez adopter deux approches :
+ Réécrivez la requête afin d’utiliser une jointure par fusion si possible. Pour cela, spécifiez les colonnes de jointure qui sont des clés de distribution et des clés de tri.
+ Si l’étape HJOIN de SVL\$1QUERY\$1SUMMARY a une très grande valeur dans le champ des lignes par rapport à la valeur des lignes de l’étape RETURN finale de la requête, vérifiez si vous pouvez réécrire la requête afin d’effectuer une jointure avec une colonne unique. Lorsqu’une requête n’effectue pas de jointure avec une colonne unique, telle qu’une clé primaire, cela augmente le nombre de lignes impliquées dans la jointure.

## Lignes fantômes ou non validées
<a name="ghost-rows-or-uncommitted-rows"></a>

Si des lignes fantômes ou non validées sont présentes, un événement d’alerte peut s’afficher dans STL\$1ALERT\$1EVENT\$1LOG indiquant un nombre de lignes fantômes excessif. Pour plus d’informations, consultez [Révision des alertes de requêtes](c-reviewing-query-alerts.md).

Pour résoudre ce problème, vous pouvez adopter deux approches :
+ Vérifiez l’onglet **Charges** de votre console Amazon Redshift pour les opérations de charge actives sur l’une des tables de requête. Si vous voyez des opérations de chargement actives, attendez qu’elles se terminent avant d’agir.
+ S’il n’y a aucune opération de charge active, exécutez [VACUUM](r_VACUUM_command.md) sur les tables de la requête pour supprimer les lignes supprimées.

## Lignes non triées ou mal triées
<a name="unsorted-or-mis-sorted-rows"></a>

Si des lignes non triées ou mal triées sont présentes, un événement d’alerte de filtre très sélectif peut s’afficher dans STL\$1ALERT\$1EVENT\$1LOG. Pour plus d’informations, consultez [Révision des alertes de requêtes](c-reviewing-query-alerts.md).

Vous pouvez également vérifier si l’une des tables de votre requête présente de grandes zones non triés en exécutant la requête [Identification des tables comportant une asymétrie des données ou des lignes non triées](identify-tables-with-data-skew-or-unsorted-rows.md).

Pour résoudre ce problème, vous pouvez adopter deux approches :
+ Exécutez [VACUUM](r_VACUUM_command.md) sur les tables de requête pour trier à nouveau les lignes.
+ Vérifiez les clés de tri des tables de la requête pour voir si des améliorations peuvent être apportées. N’oubliez pas de comparer les performances de cette requête par rapport aux performances d’autres requêtes importantes et au système global avant toute modification. Pour plus d’informations, consultez [Clés de tri](t_Sorting_data.md).

## Distribution des données sous-optimales
<a name="suboptimal-data-distribution"></a>

Si la distribution des données est sous-optimale, les éléments suivants peuvent s’afficher :
+ Un événement d’alerte d’exécution en série, de grande diffusion ou de grande distribution s’affiche dans STL\$1ALERT\$1EVENT\$1LOG. Pour plus d’informations, consultez [Révision des alertes de requêtes](c-reviewing-query-alerts.md).
+ Les tranches ne traitent pas le même nombre de lignes (approximativement) pour une étape donnée. Pour plus d’informations, consultez [Utilisation de la vue SVL\$1QUERY\$1REPORT](using-SVL-Query-Report.md).
+ Les tranches ne prennent pas autant de temps (approximativement) pour une étape donnée. Pour plus d’informations, consultez [Utilisation de la vue SVL\$1QUERY\$1REPORT](using-SVL-Query-Report.md).

Si rien de ce qui précède ne s’applique, vous pouvez également vérifier si l’une des tables de votre requête comporte une asymétrie des données en exécutant la requête dans [Identification des tables comportant une asymétrie des données ou des lignes non triées](identify-tables-with-data-skew-or-unsorted-rows.md).

Pour résoudre ce problème, vérifiez les styles de distribution des tables de la requête afin de voir si des améliorations peuvent être apportées. N’oubliez pas de comparer les performances de cette requête par rapport aux performances d’autres requêtes importantes et au système global avant toute modification. Pour plus d’informations, consultez [Distribution de données pour l’optimisation des requêtes](t_Distributing_data.md).

## Mémoire insuffisante allouée à la requête
<a name="insufficient-memory-allocated-to-the-query"></a>

Si la mémoire allouée à votre requête est insuffisante, vous pouvez voir qu’une étape de SVL\$1QUERY\$1SUMMARY comporte une valeur true pour `is_diskbased`. Pour plus d’informations, consultez [Utilisation de la vue SVL\$1QUERY\$1SUMMARY](using-SVL-Query-Summary.md).

Pour résoudre ce problème, allouez davantage de mémoire à la requête en augmentant temporairement le nombre d’emplacements de requête qu’elle utilise. La gestion de la charge de travail (WLM) réserve des emplacements dans une file d’attente de requête équivalents à au niveau de simultanéité défini pour la file d’attente. Par exemple, une file d’attente avec un niveau de simultanéité de 5 dispose de 5 emplacements. La mémoire affectée à la file d’attente est allouée à part égale à chaque emplacement. L’affectation de plusieurs emplacements à une requête donne à celle-ci accès à la mémoire de tous ces emplacements. Pour plus d’informations sur la procédure permettant d’augmenter temporairement les emplacements d’une requête, consultez [wlm\$1query\$1slot\$1count](r_wlm_query_slot_count.md).

## Clause WHERE sous-optimale
<a name="suboptimal-WHERE-clause"></a>

Si votre clause WHERE entraîne des analyses de tables excessives, une étape SCAN peut s’afficher dans le segment ayant la valeur de `maxtime` la plus élevée dans SVL\$1QUERY\$1SUMMARY. Pour plus d’informations, consultez [Utilisation de la vue SVL\$1QUERY\$1SUMMARY](using-SVL-Query-Summary.md).

Pour résoudre ce problème, ajoutez une clause WHERE à la requête basée sur la colonne de tri primaire de la table la plus volumineuse. Cette approche permet de réduire le temps d’analyse. Pour plus d’informations, consultez [Bonnes pratiques Amazon Redshift pour la conception de tables](c_designing-tables-best-practices.md).

## Prédicat pas assez restrictif
<a name="insufficiently-restrictive-predicate"></a>

Si votre requête a un prédicat qui n’est pas suffisamment restrictif, une étape SCAN peut s’afficher dans le segment avec la valeur de `maxtime` la plus élevée dans SVL\$1QUERY\$1SUMMARY avec une valeur de `rows` très importante par rapport à la valeur de `rows` de l’étape RETURN finale de la requête. Pour plus d’informations, consultez [Utilisation de la vue SVL\$1QUERY\$1SUMMARY](using-SVL-Query-Summary.md).

Pour résoudre ce problème, essayez d’ajouter un prédicat à la requête ou de rendre le prédicat existant plus restrictifs pour affiner les données de sortie.

## Ensemble de résultats très volumineux
<a name="very-large-result-set"></a>

Si votre requête renvoie un ensemble de résultats très volumineux, envisagez de réécrire la requête pour utiliser [UNLOAD](r_UNLOAD.md) afin d’écrire les résultats sur Amazon S3. Cette approche permettra d’améliorer les performances de l’étape RETURN en tirant parti du traitement parallèle. Pour plus d’informations sur la recherche d’un ensemble de résultats très volumineux, consultez [Utilisation de la vue SVL\$1QUERY\$1SUMMARY](using-SVL-Query-Summary.md).

## Longue liste SELECT
<a name="large-SELECT-list"></a>

Si votre requête comporte une liste SELECT inhabituellement longue, une valeur de `bytes` élevée peut s’afficher par rapport à la valeur de `rows` de n’importe quelle étape (comparée à d’autres étapes) dans SVL\$1QUERY\$1SUMMARY. Cette valeur de `bytes` élevée peut indiquer que vous sélectionnez un grand nombre de colonnes. Pour plus d’informations, consultez [Utilisation de la vue SVL\$1QUERY\$1SUMMARY](using-SVL-Query-Summary.md).

Pour résoudre ce problème, vérifiez les colonnes que vous sélectionnez pour voir si certaines peuvent être supprimées.

# Requêtes de diagnostics pour l’ajustement des requêtes
<a name="diagnostic-queries-for-query-tuning"></a>

Utilisez les requêtes suivantes pour identifier les problèmes rencontrés par les requêtes ou les tables sous-jacentes susceptibles d’affecter les performances des requêtes. Nous recommandons d’utiliser ces requêtes conjointement aux processus d’ajustement des requêtes expliqués dans la section [Analyse et amélioration des requêtes](c-query-tuning.md).

**Note**  
Ces requêtes concernent les clusters alloués Amazon Redshift. Ces requêtes ne sont pas destinées à être utilisées avec les groupes de travail Redshift sans serveur.

**Topics**
+ [Identification des requêtes particulièrement indiquées pour un ajustement](identify-queries-that-are-top-candidates-for-tuning.md)
+ [Identification des tables comportant une asymétrie des données ou des lignes non triées](identify-tables-with-data-skew-or-unsorted-rows.md)
+ [Identification des requêtes avec des boucles imbriquées](identify-queries-with-nested-loops.md)
+ [Vérification des temps d’attente des requêtes dans les files d’attente](review-queue-wait-times-for-queries.md)
+ [Vérification des alertes de requêtes par table](review-query-alerts-by-table.md)
+ [Identification des tables avec des statistiques manquantes](identify-tables-with-missing-statistics.md)

# Identification des requêtes particulièrement indiquées pour un ajustement
<a name="identify-queries-that-are-top-candidates-for-tuning"></a>

La requête suivante identifie les 50 instructions les plus chronophages exécutées au cours des 7 derniers jours. Vous pouvez utiliser les résultats pour identifier les requêtes inhabituellement longues. Vous pouvez également identifier les requêtes exécutées fréquemment (celles qui apparaissent plusieurs fois dans l’ensemble de résultats). Ces requêtes nécessitent souvent un ajustement en vue d’améliorer les performances du système.

Cette requête fournit également un nombre d’événements d’alertes associés à chaque requête identifiée. Ces alertes fournissent des détails utiles pour améliorer les performances de la requête. Pour plus d’informations, consultez [Révision des alertes de requêtes](c-reviewing-query-alerts.md).

```
select trim(database) as db, count(query) as n_qry, 
max(substring (qrytext,1,80)) as qrytext, 
min(run_minutes) as "min" , 
max(run_minutes) as "max", 
avg(run_minutes) as "avg", sum(run_minutes) as total,  
max(query) as max_query_id, 
max(starttime)::date as last_run, 
sum(alerts) as alerts, aborted
from (select userid, label, stl_query.query, 
trim(database) as database, 
trim(querytxt) as qrytext, 
md5(trim(querytxt)) as qry_md5, 
starttime, endtime, 
(datediff(seconds, starttime,endtime)::numeric(12,2))/60 as run_minutes,     
alrt.num_events as alerts, aborted 
from stl_query 
left outer join 
(select query, 1 as num_events from stl_alert_event_log group by query ) as alrt 
on alrt.query = stl_query.query
where userid <> 1 and starttime >=  dateadd(day, -7, current_date)) 
group by database, label, qry_md5, aborted
order by total desc limit 50;
```

# Identification des tables comportant une asymétrie des données ou des lignes non triées
<a name="identify-tables-with-data-skew-or-unsorted-rows"></a>

La requête suivante identifie les tables comportant une distribution irrégulière de données (asymétrie des données) ou un pourcentage élevé de lignes non triées.

Un valeur de `skew` faible indique que les données de la table sont correctement distribuées. Si une table comporte une valeur de `skew` de 4,00 ou plus, envisagez de modifier le style de distribution de données. Pour plus d’informations, consultez [Distribution des données sous-optimales](query-performance-improvement-opportunities.md#suboptimal-data-distribution).

Si une table comporte une valeur de `pct_unsorted` supérieure à 20 pour cent, envisagez d’exécuter la commande [VACUUM](r_VACUUM_command.md). Pour plus d’informations, consultez [Lignes non triées ou mal triées](query-performance-improvement-opportunities.md#unsorted-or-mis-sorted-rows).

Vous devez également examiner les valeurs de `mbytes` et de `pct_of_total` pour chaque table. Ces colonnes identifient la taille de la table et le pourcentage d’espace sur le disque brut que la table consomme. L’espace disque brut comprend l’espace qui est réservé par Amazon Redshift pour un usage interne, il est donc plus grand que la capacité nominale du disque, qui est la quantité d’espace disque disponible pour l’utilisateur. Ces informations vous permettront de vérifier que l’espace disque est égal à au moins 2,5 fois la taille de votre table la plus volumineuse. Cet espace disponible permet au système d’écrire des résultats intermédiaires sur le disque lors du traitement de requêtes complexes. 

```
select trim(pgn.nspname) as schema, 
trim(a.name) as table, id as tableid, 
decode(pgc.reldiststyle,0, 'even',1,det.distkey ,8,'all') as distkey, dist_ratio.ratio::decimal(10,4) as skew, 
det.head_sort as "sortkey", 
det.n_sortkeys as "#sks", b.mbytes,  
decode(b.mbytes,0,0,((b.mbytes/part.total::decimal)*100)::decimal(5,2)) as pct_of_total, 
decode(det.max_enc,0,'n','y') as enc, a.rows, 
decode( det.n_sortkeys, 0, null, a.unsorted_rows ) as unsorted_rows , 
decode( det.n_sortkeys, 0, null, decode( a.rows,0,0, (a.unsorted_rows::decimal(32)/a.rows)*100) )::decimal(5,2) as pct_unsorted 
from (select db_id, id, name, sum(rows) as rows, 
sum(rows)-sum(sorted_rows) as unsorted_rows 
from stv_tbl_perm a 
group by db_id, id, name) as a 
join pg_class as pgc on pgc.oid = a.id
join pg_namespace as pgn on pgn.oid = pgc.relnamespace
left outer join (select tbl, count(*) as mbytes 
from stv_blocklist group by tbl) b on a.id=b.tbl
inner join (select attrelid, 
min(case attisdistkey when 't' then attname else null end) as "distkey",
min(case attsortkeyord when 1 then attname  else null end ) as head_sort , 
max(attsortkeyord) as n_sortkeys, 
max(attencodingtype) as max_enc 
from pg_attribute group by 1) as det 
on det.attrelid = a.id
inner join ( select tbl, max(mbytes)::decimal(32)/min(mbytes) as ratio 
from (select tbl, trim(name) as name, slice, count(*) as mbytes
from svv_diskusage group by tbl, name, slice ) 
group by tbl, name ) as dist_ratio on a.id = dist_ratio.tbl
join ( select sum(capacity) as  total
from stv_partitions where part_begin=0 ) as part on 1=1
where mbytes is not null 
order by  mbytes desc;
```

# Identification des requêtes avec des boucles imbriquées
<a name="identify-queries-with-nested-loops"></a>

La requête suivante identifie les requêtes ayant des événements d’alertes consignés pour des boucles imbriquées. Pour plus d’informations sur la façon de corriger la condition de boucle imbriquée, consultez [Boucle imbriquée](query-performance-improvement-opportunities.md#nested-loop).

```
select query, trim(querytxt) as SQL, starttime 
from stl_query 
where query in (
select distinct query 
from stl_alert_event_log 
where event like 'Nested Loop Join in the query plan%') 
order by starttime desc;
```

# Vérification des temps d’attente des requêtes dans les files d’attente
<a name="review-queue-wait-times-for-queries"></a>

La requête suivante affiche combien de temps les requêtes récentes ont attendu avant qu’un emplacement s’ouvre dans une file d’attente avant leur exécution. Si vous voyez une tendance de temps d’attente élevés, vous pouvez modifier la configuration de votre file d’attente de requête pour obtenir un débit plus élevé. Pour plus d’informations, consultez [Implémentation de la gestion manuelle de la charge de travail](cm-c-defining-query-queues.md).

```
select trim(database) as DB , w.query, 
substring(q.querytxt, 1, 100) as querytxt,  w.queue_start_time, 
w.service_class as class, w.slot_count as slots, 
w.total_queue_time/1000000 as queue_seconds, 
w.total_exec_time/1000000 exec_seconds, (w.total_queue_time+w.total_Exec_time)/1000000 as total_seconds 
from stl_wlm_query w 
left join stl_query q on q.query = w.query and q.userid = w.userid 
where w.queue_start_Time >= dateadd(day, -7, current_Date) 
and w.total_queue_Time > 0  and w.userid >1   
and q.starttime >= dateadd(day, -7, current_Date) 
order by w.total_queue_time desc, w.queue_start_time desc limit 35;
```

# Vérification des alertes de requêtes par table
<a name="review-query-alerts-by-table"></a>

La requête suivante identifie les tables pour lesquelles des événements d’alertes de requêtes ont été consignés, ainsi que les types d’alertes rencontrés le plus souvent.

Si la valeur de `minutes` pour une ligne avec une table identifiée est élevée, vérifiez cette table pour savoir si elle nécessite des opérations de maintenance habituelles, comme l’exécution de [ANALYSE](r_ANALYZE.md) ou de [VACUUM](r_VACUUM_command.md).

Si la valeur de `count` est élevée pour une ligne, mais que la valeur de `table` est null, exécutez une requête sur STL\$1ALERT\$1EVENT\$1LOG pour la valeur de `event` associée afin d’étudier pourquoi cette alerte est déclenchée si souvent.

```
select trim(s.perm_table_name) as table, 
(sum(abs(datediff(seconds, s.starttime, s.endtime)))/60)::numeric(24,0) as minutes, trim(split_part(l.event,':',1)) as event,  trim(l.solution) as solution, 
max(l.query) as sample_query, count(*) 
from stl_alert_event_log as l 
left join stl_scan as s on s.query = l.query and s.slice = l.slice 
and s.segment = l.segment and s.step = l.step
where l.event_time >=  dateadd(day, -7, current_Date) 
group by 1,3,4 
order by 2 desc,6 desc;
```

# Identification des tables avec des statistiques manquantes
<a name="identify-tables-with-missing-statistics"></a>

La requête suivante fournit un nombre de requêtes que vous exécutez sur les tables pour lesquelles des statistiques sont manquantes. Si cette requête renvoie toutes les lignes, examinez la valeur de `plannode` afin de déterminer la table concernée et exécutez [ANALYSE](r_ANALYZE.md) sur celle-ci.

```
select substring(trim(plannode),1,100) as plannode, count(*) 
from stl_explain 
where plannode like '%missing statistics%' 
group by plannode 
order by 2 desc;
```