
Amazon Redshift DB開発者ガイド – クエリパフォーマンスチューニング(2).クエリのメモリ使用方法管理
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
目次
クエリのメモリ使用管理
Amazon Redshiftは、クエリにがメモリ内で実行するか、また必要に応じてディスクへのクエリの中間結果をスワップ(交換)するための機能をサポートしています。
Amazon Redshiftのクエリパフォーマンス結果が予想よりも遅くなっている場合、クエリクエリ実行の少なくとも一部のディスクへの書き込みをされるかもしれません。メモリ内で完全に実行されるクエリは、頻繁にディスク間でデータを転送されるクエリよりも高速に動作します。
Amazon RedshiftはDELETE文、ソート、ハッシュ、及びSELECT文での集約の為にディスクに中間結果を書き込む事が出来ます。ディスクに中間結果を書き込むと、クエリがシステムメモリの限界に達した場合でも実行し続ける事を保証します。(追加のディスクI/Oがパフォーマンスを低下させてしまいますが)
最初のステップは、クエリをメモリ内に維持する事では無く、ディスクに中間結果を書き込むかどうかを決定する事です。その後、手順がディスクへの書き込みをされているかを識別するために実行計画とシステムテーブルを使用する事が出来ます。
クエリがディスク書き込みを行うかどうかを決める
任意のクエリ手順が特定のクエリのためにディスクに中間結果を書き込んだかどうかを判断するには、システムテーブルクエリ所定のセットを使用します。SELECTとDELETEステートメントの両方を含む、ディスクに書き込む事が出来るクエリのタイプに、このメソッドを用います。
- 1.調査対象となるクエリのIDを判別するには、以下の問い合わせ文を発行します。
select query, elapsed, substring from svl_qlog order by query desc limit 5;
- このクエリはクエリID、実行時kな、及び以下に示すように、データベーステーブルに対して実行する直近5つのクエリテキスト(所定文字数以降は切り捨てられている形)を表示します。
query| elapsed | substring -----+---------+----------------------------------------------------- 1026 | 9574270 | select s.seg, s.maxtime, s.label, s.is_diskbased from query_ 1025 | 18672594| select t1.c1 x1, t2.c2 x2 from tbig t1, tbig t2 where t1.c1 1024 | 84266 | select count(*) as underrepped from ( select count(*) as a f 1023 | 83217 | select system_status from stv_gui_status 1022 | 39236 | select * from stv_sessions (5 rows)
- 2.調査しているクエリに一致するクエリIDを決定する為に、出力内容を調べます。
- 3.クエリIDを使用して、クエリの任意の手順がディスクに書き込みを行ったかを判断する為に以下のクエリを発行します。以下例では、クエリID:1025を使用しています。
select query, step, rows, workmem, label, is_diskbased from svl_query_summary where query = 1025 order by workmem desc;
- このクエリは以下の様な結果を返します。
query| step| rows | workmem | label | is_diskbased -----+-----+--------+-----------+---------------+-------------- 1025 | 0 |16000000| 43205240 |scan tbl=9 | f 1025 | 2 |16000000| 43205240 |hash tbl=142 | t 1025 | 0 |16000000| 55248 |scan tbl=116536| f 1025 | 2 |16000000| 55248 |dist | f (4 rows)
- 4.出力内容に目を通してみます。もしいずれかの手順でIS_DISKBASEDがtrue("t")の場合、その手順ではディスクにデータ書き込みを行っています。前述の例では、ハッシュ工程の中間結果がディスクに書き込まれた形となりました。
- 手順がディスクへの書き込みとパフォーマンスに影響を与えている事が判明した場合、もっとも簡単な解決策はクエリのスロット数を増やし、クエリに使用可能なメモリを増やす事です。ワークロード管理(WLM)は、クラスタ(例えば同時実行レベルが5に設定されている場合、そのクエリは5つのスロットを持っている)に設定された同時実行レベルに応じてクエリキュー内のスロットを有します。WLMは各スロットにクエリで使用可能なメモリを割り当てます。スロット数はwlm_query_slot_countパラメータで設定されています。スロット数を増やすと、クエリの使用可能なメモリの量を増加させます。
クエリがどの手順をディスクに書き込むかを決める
クエリ内の手順がディスクに書き込みを行っているかどうかを確認するには、幾つかのシステムテーブルのクエリと併せて、EXPLAINコマンドを使用します。
このセクションでは、ディスクへの書き込みを行うハッシュ結合について検討する為に、EXPLAINやSVL_QLOG、SVL_QUERY_SUMMARYシステムテーブルを使用するプロセスについて解説して行きます。
以下のクエリを調べて行きます:
select t1.c1 x1, t2.c2 x2
from tbig t1, tbig t2
where t1.c1 = t2.c2;
- 1.クエリのプランを表示するには、以下のEXPLAINコマンドを実行します。
explain select t1.c1 x1, t2.c2 x2 from tbig t1, tbig t2 where t1.c1 = t2.c2;
- このコマンドは以下のような出力結果を返します。
- この計画は、クエリが最も内側のノードから始まり、外側のノードに継続的に実行されている事を示しています。クエリは、ハッシュを使用して実行されます。大規模なデータセット、ハッシュや集約、ソートのは、システムがクエリ処理用に割り当てられた十分なメモリを持っていない場合に、ディスクにデータを書き込む可能性が高いリレーショナル演算子です。
QUERY PLAN -------------------------------------------------------------- XN Hash Join DS_DIST_INNER (cost=200000.00..40836025765.37 rows=90576537 width=8) Hash Cond: ("outer".c1 = "inner".c2) -> XN Seq Scan on tbig t1 (cost=0.00..160000.00 rows=16000000 width=4) -> XN Hash (cost=160000.00..160000.00 rows=16000000 width=4) -> XN Seq Scan on tbig t2 (cost=0.00..160000.00 rows=16000000 width=4) (5 rows)
- 2.実際にクエリを発行するには、以下の問い合わせを発行します。
- 3.直前に実行したクエリのクエリIDを取得するSVL_QLOGビューを使用するには以下の問い合わせ文を発行します。
select query, elapsed, substring from svl_qlog order by query desc limit 5;
- このコマンドでは、Amazon Redshiftで実行した直近5つのクエリが表示されます。
- TBIGから選択するクエリは、IDが1033である事が分かります。
query | elapsed | substring -------+---------+------------------------------------------------ 1033 | 4592158 | select t1.c1 x1, t2.c2 x2 from tbig t1, tbig t2 1032 | 477285 | select query, step, rows, memory, label, 1031 | 23742 | select query, elapsed, substring from svl_qlog 1030 | 900222 | select * from svl_query_summary limit 5; 1029 | 1304248 | select query, step, rows, memory, label, (5 rows)
- 4.どのリレーショナル演算子が計画から(もしあれば)ディスクに書かれたのかを確認するために、前のステップからのクエリIDを使用して、SVL_QUERY_SUMMARYビューを表示します。このクエリグループの実施手順、及び処理された行数をを表示するには:
select query, step, rows, workmem, label, is_diskbased from svl_query_summary where query = 1033 order by workmem desc;
- 結果は以下のような内容が返って来ます。
query| step| rows | workmem | label | is_diskbased -----+-----+--------+-----------+---------------+-------------- 1033 | 0 |16000000| 141557760 |scan tbl=9 | f 1033 | 2 |16000000| 135266304 |hash tbl=142 | t 1033 | 0 |16000000| 128974848 |scan tbl=116536| f 1033 | 2 |16000000| 122683392 |dist | f (4 rows)
- 5.svl_query_summaryの出力と、EXPLAINステートメントによって生成された計画を比較します。
- クエリの手順が計画に於いてどの場所に対応しているかを確認する為に結果を確認する事が出来ます。もしこれらのステップがディスクに行っている場合、どの程度の行が処理されており、またクエリを変更したりワークロード管理(WLM)構成を調整出来るようにどの程度メモリが使われているかを決定する為に情報を使用します。
- 詳細については、Implementing workload managementをご参照ください。
select t1.c1 x1, t2.c2 x2
from tbig t1, tbig t2
where t1.c1 = t2.c2 ;