Help us improve the AWS re:Post Knowledge Center by sharing your feedback in a brief survey. Your input can influence how we create and update our content to better support your AWS journey.
クエリプランと Amazon Redshift のクエリレポートを関連付けるにはどうすればよいですか?
クエリプランを Amazon Redshift クラスターのクエリレポートと関連付けたいと考えています。
簡単な説明
Amazon Redshift でクエリを実行するのに必要な使用方法を判断するには、EXPLAIN コマンドを実行します。EXPLAIN コマンドから返される実行プランには、関連するクエリプランと実行ステップの概要が記載されています。次に、SVL_QUERY_REPORT システムビューを使用して、クラスタスライスレベルでクエリ情報を表示します。スライスレベルの情報を使用して、クエリのパフォーマンスに影響を与える可能性のあるクラスター全体で不均一なデータ分散を検出できます。
Amazon Redshift はクエリプランを処理し、ステップ、セグメント、ストリームに変換します。詳細については、「クエリプランと実行ワークフロー」を参照してください。
解決策
テーブルを作成し、クエリの実行プランと SVL クエリレポートを取得する
テーブルを作成して実行プランと SVL クエリレポートを取得するには、次の手順を実行します。
-
分散キーで結合操作が実行されなかった場合、次のクエリを実行します。
select eventname, sum (pricepaid) from sales, event where sales.eventid = event.eventid group by eventname order by 2 desc;このクエリは、内部テーブルをすべてのコンピュートノードに分散します。
-
クエリプランを取得します:
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) -
SVL_QUERY_REPORT クエリを実行してクエリレポートを取得します。
select * from svl_query_report where query = query_id order by segment, step, elapsed_time, rows;**注:**query_id はご自分のクエリの ID に置き換えます。
クエリプランをクエリレポートをマッピングする
クエリプランをクエリレポートにマッピングするには、次の手順を実行します。
- 次のクエリを実行して、セグメント値が 0 のクエリの svl_query_report を取得します。
以下はログの例です。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)
上記の出力では、セグメント値が 0 の場合、Amazon Redshift はシーケンシャルスキャン操作を実行してイベントテーブルをスキャンします。シーケンシャルスキャン操作は**[ラベル]** 列にあります。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) - 次のクエリを実行して、セグメント値が 1 のクエリの svl_query_report を取得します。
以下はログの例です。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;
クエリの実行は、セグメント値が 1 になるまで継続されます。ハッシュテーブル操作は、結合の内部テーブルで実行されます。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) - 次のクエリを実行して、セグメント値が 2 のクエリの svl_query_report を取得します。
以下はログの例です。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)
前の例では、セグメント値が 2 のときにクエリが実行され、順次スキャン操作を実行して売上テーブルをスキャンします。同じセグメントで、集計操作を実行して結果を集約し、次にハッシュ結合操作を実行してテーブルを結合します。いずれかのテーブルの結合列は、分散キーでもソートキーでもありません。その結果、内部テーブルは DS_BCAST_INNER としてすべてのコンピュートノードに分散されます。これで、実行プランの内部テーブルが表示されます。このクエリを実行して、セグメント値が 3、4、5 のクエリの SVL_QUERY_REPORT を取得することもできます。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)
これらのセグメントで実行されるハッシュ集計操作とソート操作は、「aggr」と「sort」というラベルで識別されます。ハッシュ集計操作は、ソートされていないグループ化された集計関数に対して実行されます。ソート操作は ORDER BY 句を評価するために実行されます。
すべてのセグメントが使用された後、クエリはセグメント 4 と 5 でネットワーク操作を実行し、中間結果をリーダーノードに送信します。結果はリーダーノードに送信され、追加の処理が行われます。結果は「返品」ラベルで確認できます。
クエリが完了したら、次のクエリを実行して、クエリの実行時間をミリ秒単位で確認します。
select datediff (ms, exec_start_time, exec_end_time) from stl_wlm_query where query= 938787; date_diff ----------- 101 (1 row)
クエリを最適化
クエリプランを分析すると、ユースケースに基づいてクエリのパフォーマンスを調整できます。詳細については、「Top 10 performance tuning techniques for Amazon Redshift」を参照してください。
