Wie korreliere ich den Abfrageplan mit dem Abfragebericht in Amazon Redshift?

Lesedauer: 8 Minute
0

Ich möchte den Abfrageplan mit dem Abfragebericht in meinem Amazon-Redshift-Cluster korrelieren.

Kurzbeschreibung

Um die Nutzung zu ermitteln, die für die Ausführung einer Abfrage in Amazon Redshift erforderlich ist, führen Sie den Befehl EXPLAIN aus. Der Ausführungsplan, der vom Befehl EXPLAIN zurückgegeben wird, beschreibt die beteiligten Abfrageplanungs- und Ausführungsschritte. Verwenden Sie dann die Systemansicht SVL_QUERY_REPORT, um Abfrageinformationen auf Cluster-Slice-Ebene anzuzeigen. Sie können die Informationen auf Slice-Ebene verwenden, um eine ungleichmäßige Datenverteilung im Cluster zu erkennen, die sich auf die Abfrageleistung auswirken kann.

Amazon Redshift verarbeitet den Abfrageplan und übersetzt den Plan in Schritte, Segmente und Streams. Weitere Informationen finden Sie unter Arbeitsablauf für die Abfrageplanung und -ausführung.

Lösung

Erstellen einer Tabelle und Abrufen des Ausführungsplans und des SVL-Abfrageberichts für die Abfrage

Gehen Sie wie folgt vor, um eine Tabelle zu erstellen und den Ausführungsplan und den SVL-Abfragebericht abzurufen:

  1. Erstellen Sie zwei Tabellen mit unterschiedlichen Sortier- und Verteilungsschlüsseln.

  2. Führen Sie die folgende Abfrage aus, bei der kein Join-Vorgang für einen Verteilungsschlüssel ausgeführt wurde:

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

    Diese Abfrage verteilt die innere Tabelle an alle Rechenknoten.

  3. Rufen Sie den Abfrageplan ab:

    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. Führen Sie die Abfrage SVL_QUERY_REPORT aus, um den Abfragebericht abzurufen:

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

    Hinweis: Ersetzen Sie query_id durch die ID Ihrer Abfrage.

Zuordnen des Abfrageplans zum Abfragebericht

Gehen Sie wie folgt vor, um den Abfrageplan dem Abfragebericht zuzuordnen:

  1. Führen Sie die folgende Abfrage aus, um den svl_query_report für eine Abfrage mit einem Segmentwert von 0 abzurufen:
    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)
    Das Folgende ist eine Beispielausgabe:
    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)
    Wenn der Segmentwert in der vorherigen Ausgabe 0 ist, führt Amazon Redshift einen sequentiellen Scanvorgang durch, um die Ereignistabelle zu scannen. Den sequentiellen Scanvorgang finden Sie in der Spalte label.
  2. Führen Sie die folgende Abfrage aus, um den svl_query_report für eine Abfrage mit einem Segmentwert von 1 abzurufen:
    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;
    Das Folgende ist eine Beispielausgabe:
    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)
    Die Abfrage wird so lange ausgeführt, bis der Segmentwert 1 ist. Eine Hash-Tabellenoperation wird für die innere Tabelle beim Join ausgeführt.
  3. Führen Sie die folgende Abfrage aus, um den svl_query_report für eine Abfrage mit einem Segmentwert von 2 abzurufen:
    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)
    Das Folgende ist eine Beispielausgabe:
    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)
    Im vorherigen Beispiel wird die Abfrage ausgeführt, wenn der Segmentwert 2 ist, und es wird ein sequentieller Scanvorgang durchgeführt, um die Tabelle sales zu scannen. Im selben Segment wird eine Aggregatoperation ausgeführt, um Ergebnisse zu aggregieren, und anschließend wird eine Hash-Join-Operation ausgeführt, um Tabellen zu verknüpfen. Die Join-Spalten für eine der Tabellen sind keine Verteilungs- oder Sortierschlüssel. Infolgedessen wird die innere Tabelle als DS_BCAST_INNER an alle Rechenknoten verteilt. Sie können dann die innere Tabelle im Ausführungsplan sehen. Sie können diese Abfrage auch ausführen, um den SVL_QUERY_REPORT für eine Abfrage mit einem Segmentwert von 3, 4 und 5 abzurufen.

In diesen Segmenten werden eine Hash-Aggregatoperation und eine Sortieroperation ausgeführt und anhand der Bezeichnungen „aggr“ und „sort“ identifiziert. Die Hash-Aggregatoperation wird für unsortierte gruppierte Aggregatfunktionen ausgeführt. Der Sortiervorgang wird ausgeführt, um die Klausel ORDER BY auszuwerten.

Nachdem alle Segmente verwendet wurden, führt die Abfrage eine Netzwerkoperation für die Segmente 4 und 5 aus, um Zwischenergebnisse an den Hauptknoten zu senden. Die Ergebnisse werden zur weiteren Verarbeitung an den Hauptknoten gesendet. Sie können die Ergebnisse mit dem Label „return“ sehen.

Führen Sie nach Abschluss der Abfrage die folgende Abfrage aus, um die Ausführungszeit der Abfrage in Millisekunden zu überprüfen:

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

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

Optimieren der Abfrage

Wenn Sie Ihren Abfrageplan analysieren, können Sie Ihre Abfrageleistung auf der ](https://docs.aws.amazon.com/redshift/latest/dg/c-optimizing-query-performance.html)Grundlage Ihres Anwendungsfalls optimieren[. Weitere Informationen finden Sie unter Die 10 wichtigsten Techniken zur Leistungsoptimierung für Amazon Redshift.

Verwandte Informationen

Zuordnen des Abfrageplans zur Abfragezusammenfassung

Überprüfen der Schritte des Abfrageplans

Verwenden der Ansicht SVL_QUERY_REPORT

AWS OFFICIAL
AWS OFFICIALAktualisiert vor 2 Monaten