Comment établir une corrélation entre le plan de requête et le rapport de requête dans Amazon Redshift ?

Lecture de 8 minute(s)
0

Je souhaite établir une corrélation entre le plan de requête et le rapport de requête de mon cluster Amazon Redshift.

Brève description

Pour déterminer l'utilisation requise pour exécuter une requête dans Amazon Redshift, exécutez la commande EXPLAIN. Le plan d'exécution renvoyé par la commande EXPLAIN décrit les étapes de planification et d'exécution des requêtes impliquées. Utilisez ensuite la vue système SVL_QUERY_REPORT pour afficher les informations de requête au niveau d'une tranche de cluster. Vous pouvez utiliser les informations au niveau des tranches pour détecter une distribution inégale des données au sein du cluster, ce qui peut affecter les performances des requêtes.

Amazon Redshift traite le plan de requête et le traduit en étapes, segments et flux. Pour plus d'informations, voir l’organisation de planification et d'exécution des requêtes.

Résolution

Créez une table et obtenez le plan d'exécution et le rapport de requête SVL pour la requête

Pour créer une table et obtenir le plan d'exécution et le rapport de requête SVL, procédez comme suit :

  1. Créez deux tables avec des clés de tri et des clés de distribution différentes.

  2. Exécutez la requête suivante lorsqu'aucune opération de jointure n'a été effectuée sur une clé de distribution :

    select eventname, sum (pricepaid) from sales, event where sales.eventid = event.eventid group by eventname order by 2 desc;

    Cette requête distribue la table interne à tous les nœuds de calcul.

  3. Récupérez le plan de requête :

    EXPLAIN <query>;
                                                   QUERY PLAN                                               
    --------------------------------------------------------------------------------------------------------
    XN Merge  (cost=1002815368414.24..1002815368415.67 rows=571 width=27)
       Merge Key: sum(sales.pricepaid)
       ->  XN Network  (cost=1002815368414.24..1002815368415.67 rows=571 width=27)
             Send to leader
             ->  XN Sort  (cost=1002815368414.24..1002815368415.67 rows=571 width=27)
                   Sort Key: sum(sales.pricepaid)
                   ->  XN HashAggregate  (cost=2815368386.67..2815368388.10 rows=571 width=27)
                         ->  XN Hash Join DS_BCAST_INNER  (cost=109.98..2815367496.05 rows=178125 width=27)
                               Hash Cond: ("outer".eventid = "inner".eventid)
                               ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=14)
                               ->  XN Hash  (cost=87.98..87.98 rows=8798 width=21)
                                     ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=21)
    (12 rows)
  4. Exécutez la requête SVL_QUERY_REPORT pour obtenir le rapport de requête :

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

    **Remarque :**Remplacez query_id par l'ID de votre requête.

Mappez le plan de requête avec le rapport de requête

Pour mapper le plan de requête avec le rapport de requête, procédez comme suit :

  1. Exécutez la requête suivante pour obtenir le svl_query_report pour une requête dont la valeur de segment est 0 :
    select query,slice,segment,step,start_time,end_time,elapsed_time,rows,bytes,label from svl_query_report where query = 938787 and segment = 0 order by segment, step, elapsed_time, rows;
    
    EXPLAIN <query>;
    ->  XN Hash  (cost=87.98..87.98 rows=8798 width=21)
       ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=21)
    Vous trouverez ci-dessous un exemple de journal :
    query  | slice | segment | step |         start_time         |         end_time          | elapsed_time | rows | bytes  |            label              
    -------+-------+---------+------+----------------------------+---------------------------+--------------+------+--------+------------------------------
    938787 |     0 |       0 |    0 | 2020-05-22 11:11:48.828309 | 2020-05-22 11:11:48.82987 |         1561 | 4383 | 128626 | scan   tbl=278788 name=event
    938787 |     1 |       0 |    0 | 2020-05-22 11:11:48.828309 | 2020-05-22 11:11:48.82987 |         1561 | 4415 | 128918 | scan   tbl=278788 name=event
    938787 |     0 |       0 |    1 | 2020-05-22 11:11:48.828309 | 2020-05-22 11:11:48.82987 |         1561 | 4383 |      0 | project                     
    938787 |     1 |       0 |    1 | 2020-05-22 11:11:48.828309 | 2020-05-22 11:11:48.82987 |         1561 | 4415 |      0 | project                     
    938787 |     0 |       0 |    2 | 2020-05-22 11:11:48.828309 | 2020-05-22 11:11:48.82987 |         1561 | 4383 | 126660 | bcast                      
    ...
    
    (6 rows)
    Dans la sortie précédente, lorsque la valeur du segment est 0, Amazon Redshift effectue une opération d’analyse séquentiel de la table des événements. L'opération d’analyse séquentielle se trouve dans la colonne des étiquettes.
  2. Exécutez la requête suivante pour obtenir le svl_query_report pour une requête dont la valeur de segment est égale à 1 :
    select query,slice,segment,step,start_time,end_time,elapsed_time,rows,bytes,label from svl_query_report where query = 938787 and segment = 1 order by segment, step, elapsed_time, rows;
    Vous trouverez ci-dessous un exemple de journal :
    query  | slice | segment | step |       start_time          |          end_time          | elapsed_time | rows | bytes  |     label           
    -------+-------+---------+------+---------------------------+----------------------------+--------------+------+--------+-------------------------------------------
    938787 |     1 |       1 |    0 | 2020-05-22 11:11:48.826864 | 2020-05-22 11:11:48.830037 |         3173 |    0 |      0 | scan   tbl=376297 name=Internal Worktable  
    938787 |     0 |       1 |    0 | 2020-05-22 11:11:48.826864 | 2020-05-22 11:11:48.831142 |         4278 | 8798 | 253580 | scan   tbl=376297 name=Internal Worktable
    938787 |     1 |       1 |    1 | 2020-05-22 11:11:48.826864 | 2020-05-22 11:11:48.830037 |         3173 |    0 |      0 | project                                   
    938787 |     0 |       1 |    1 | 2020-05-22 11:11:48.826864 | 2020-05-22 11:11:48.831142 |         4278 | 8798 |      0 | project                                   
    938787 |     1 |       1 |    2 | 2020-05-22 11:11:48.826864 | 2020-05-22 11:11:48.830037 |         3173 |    0 |      0 | hash   tbl=439                            
    ...                        
    
    (6 rows)
    La requête continue de s'exécuter jusqu'à ce que la valeur du segment soit égale à 1. Une opération de table de hachage est effectuée sur la table interne de la jointure.
  3. Exécutez la requête suivante pour obtenir le svl_query_report pour une requête dont la valeur de segment est 2 :
    select query,slice,segment,step,start_time,end_time,elapsed_time,rows,bytes,label from svl_query_report where query = 938787 and segment = 2 order by segment, step, elapsed_time, rows;
    
    EXPLAIN <query>;
    ->  XN Hash Join DS_BCAST_INNER  (cost=109.98..2815367496.05 rows=178125 width=27)
                               Hash Cond: ("outer".eventid = "inner".eventid)
       ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=14)
    Vous trouverez ci-dessous un exemple de journal :
    query  | slice | segment | step |         start_time         |          end_time          | elapsed_time | rows  |  bytes  |            label             
    --------+-------+---------+------+----------------------------+----------------------------+--------------+-------+---------+------------------------------
    938787 |     1 |       2 |    0 | 2020-05-22 11:11:48.839297 | 2020-05-22 11:11:48.865857 |        26560 | 86519 | 1730380 | scan   tbl=278792 name=sales  
    938787 |     0 |       2 |    0 | 2020-05-22 11:11:48.838371 | 2020-05-22 11:11:48.865857 |        27486 | 85937 | 1718740 | scan   tbl=278792 name=sales  
    938787 |     1 |       2 |    1 | 2020-05-22 11:11:48.839297 | 2020-05-22 11:11:48.865857 |        26560 | 86519 |       0 | project                       
    938787 |     0 |       2 |    1 | 2020-05-22 11:11:48.838371 | 2020-05-22 11:11:48.865857 |        27486 | 85937 |       0 | project                       
    938787 |     1 |       2 |    2 | 2020-05-22 11:11:48.839297 | 2020-05-22 11:11:48.865857 |        26560 | 86519 |       0 | project                       
    938787 |     0 |       2 |    2 | 2020-05-22 11:11:48.838371 | 2020-05-22 11:11:48.865857 |        27486 | 85937 |       0 | project                       
    938787 |     1 |       2 |    3 | 2020-05-22 11:11:48.839297 | 2020-05-22 11:11:48.865857 |        26560 | 86519 |       0 | hjoin  tbl=439                
    938787 |     0 |       2 |    3 | 2020-05-22 11:11:48.838371 | 2020-05-22 11:11:48.865857 |        27486 | 85937 |       0 | hjoin  tbl=439                
    938787 |     1 |       2 |    4 | 2020-05-22 11:11:48.839297 | 2020-05-22 11:11:48.865857 |        26560 | 86519 |       0 | project                       
    938787 |     0 |       2 |    4 | 2020-05-22 11:11:48.838371 | 2020-05-22 11:11:48.865857 |        27486 | 85937 |       0 | project                       
    938787 |     1 |       2 |    5 | 2020-05-22 11:11:48.839297 | 2020-05-22 11:11:48.865857 |        26560 | 86519 |       0 | project                       
    938787 |     0 |       2 |    5 | 2020-05-22 11:11:48.838371 | 2020-05-22 11:11:48.865857 |        27486 | 85937 |       0 | project                       
    938787 |     1 |       2 |    6 | 2020-05-22 11:11:48.839297 | 2020-05-22 11:11:48.865857 |        26560 |   576 |   34916 | aggr   tbl=448                
    938787 |     0 |       2 |    6 | 2020-05-22 11:11:48.838371 | 2020-05-22 11:11:48.865857 |        27486 |   576 |   34916 | aggr   tbl=448                
    ...                        
    
    (16 rows)
    Dans l'exemple précédent, la requête est exécutée lorsque la valeur du segment est 2 et effectue une opération d’analyse séquentielle de la table des ventes. Dans le même segment, une opération d'agrégation est effectuée pour agréger les résultats, puis une opération de jointure par hachage est effectuée pour joindre des tables. Les colonnes de jointure de l'une des tables ne sont ni une clé de distribution ni une clé de tri. Par conséquent, la table interne est distribuée à tous les nœuds de calcul sous la forme DS_BCAST_INNER. Vous pouvez ensuite voir la table interne dans le plan d'exécution. Vous pouvez également exécuter cette requête pour obtenir le SVL_QUERY_REPORT pour une requête dont la valeur de segment est 3, 4 et 5.

Dans ces segments, une opération d'agrégation de hachage et une opération de tri sont effectuées et identifiées à partir des étiquettes « aggr » et « sort ». L'opération d'agrégation par hachage est effectuée sur des fonctions d'agrégation groupées non triées. L'opération de tri est effectuée pour évaluer la clause ORDER BY.

Une fois tous les segments utilisés, la requête exécute une opération réseau sur les segments 4 et 5 pour envoyer des résultats intermédiaires au nœud leader. Les résultats sont envoyés au nœud leader pour un traitement supplémentaire. Vous pouvez voir les résultats grâce à l'étiquette « retour ».

Une fois la requête terminée, exécutez la requête suivante pour vérifier le temps d'exécution de la requête en millisecondes :

select datediff (ms, exec_start_time, exec_end_time) from stl_wlm_query where query= 938787;

date_diff
-----------
101
(1 row)

Optimisation de vos requêtes

Lorsque vous analysez votre plan de requêtes, vous pouvez ajuster les performances de vos requêtes en fonction de votre cas d'utilisation. Pour plus d'informations, consultez les 10 meilleures techniques de réglage des performances pour Amazon Redshift.

Informations connexes

Mappage du plan de requête au résumé de la requête

Révision des étapes du plan de requêtes

Utilisation de la vue SVL_QUERY_REPORT

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a un mois