クエリパフォーマンスの向上
Amazon Redshift のクエリパフォーマンスに影響を与える一般的な問題と、それらの問題を診断して解決する手順を以下に示します。
トピック
テーブル統計がないか古い
テーブル統計がないか古い場合、次の状況が発生することがあります。
-
EXPLAIN コマンドの結果として警告メッセージが表示される。
-
STL_ALERT_EVENT_LOG に統計がないことを示すアラートイベントが記録される。詳細については、「クエリアラートの確認」を参照してください。
この問題を修正するには、ANALYZEを実行します。
Nested Loop
ネステッドループがある場合、STL_ALERT_EVENT_LOG にネステッドループのアラートイベントが記録されることがあります。ネステッドループにあるクエリの特定 でクエリを実行することで、このイベントタイプを識別することもできます。詳細については、「クエリアラートの確認」を参照してください。
この問題を修正するには、クエリでクロス結合を確認し、可能であれば削除します。クロス結合は、2 つのテーブルのデカルト積を算出する結合条件のない結合です。これらは通常、可能な結合タイプの中で最も遅いネステッドループ結合として実行されます。
ハッシュ結合
ハッシュ結合が存在する場合、次の状況が発生する可能性があります。
-
クエリプランにハッシュおよびハッシュ結合操作がある。詳細については、「クエリプランの分析」を参照してください。
-
SVL_QUERY_SUMMARY の maxtime 値が最も大きいセグメントに HJOIN ステップがある。詳細については、「SVL_QUERY_SUMMARY ビューの使用」を参照してください。
この問題を修正するには、いくつかの方法を実行することができます。
-
可能であれば、マージ結合を使用するようにクエリを書き換えます。これは、分散キーおよびソートキーの両方である結合列を指定することで行うことができます。
-
SVL_QUERY_SUMMARY 内の HJOIN ステップにある行の値が、クエリ内の最後の RETURN ステップにある行と比較して非常に大きい場合、クエリを書き換えて一意の列で結合することができるかどうかを確認します。クエリが一意の列 (プライマリキーなど) で結合されない場合、結合に関係する行数が増加します。
非実体行または未コミット行
非実体行または未コミット行が存在する場合、非実体行が多すぎることを示すアラートイベントが STL_ALERT_EVENT_LOG に記録されることがあります。詳細については、「クエリアラートの確認」を参照してください。
この問題を修正するには、いくつかの方法を実行することができます。
-
クエリテーブルのアクティブなロードオペレーションについては、Amazon Redshift コンソールの [Loads (ロード)] タブを確認してください。アクティブなロード操作がある場合、アクションを実行する前にそれらの操作が完了するまで待ちます。
-
アクティブなロード操作がない場合、クエリテーブルで VACUUM を実行して、削除済みの行を除去します。
未ソート行または正しくソートされていない行
未ソート行または正しくソートされていない行が存在する場合、STL_ALERT_EVENT_LOG にかなり限定的なアラートイベントが記録されることがあります。詳細については、「クエリアラートの確認」を参照してください。
データスキューまたは未ソート行のあるテーブルの特定 でクエリを実行することにより、クエリ内のいずれかのテーブルに未ソート領域が大量にあるかどうかを確認することもできます。
この問題を修正するには、いくつかの方法を実行することができます。
十分最適でないデータ分散
データ分散が十分に最適でない場合、次の状況が発生する可能性があります。
-
直列実行、大量のブロードキャスト、または大量の分散に関するアラートイベントが STL_ALERT_EVENT_LOG に記録される。詳細については、「クエリアラートの確認」を参照してください。
-
各スライスがあるステップについて処理している行の数が大きく異なる。詳細については、「SVL_QUERY_REPORT ビューの使用」を参照してください。
-
各スライスがあるステップにかけている時間が大きく異なる。詳細については、「SVL_QUERY_REPORT ビューの使用」を参照してください。
上記のどれもあてはまらない場合、データスキューまたは未ソート行のあるテーブルの特定でクエリを実行することにより、クエリ内のいずれかのテーブルにデータスキューがないかどうかを確認することもできます。
この問題を修正するには、クエリ内のテーブルの分散スタイルを確認して、改善できる点がないかを調べます。変更を加える前に、必ずこのクエリのパフォーマンスと他の重要なクエリやシステム全体のパフォーマンスを比較検討してください。詳細については、「クエリ最適化のためのデータのディストリビューション」を参照してください。
クエリに割り当てられてメモリが不十分
クエリに割り当てられたメモリが不十分な場合、is_diskbased
値が true のステップが SVL_QUERY_SUMMARY に存在する可能性があります。詳細については、「SVL_QUERY_SUMMARY ビューの使用」を参照してください。
この問題を修正するには、クエリが使用するクエリスロットの数を一時的に増やして、クエリに多くのメモリを割り当てます。ワークロード管理 (WLM) は、キューに設定された同時実行レベルと同等のスロットをクエリキューに確保します。例えば、同時実行レベルが 5 のキューには 5 つのスロットがあります。キューに割り当てられたメモリは、各スロットに均等に割り当てられます。1 つのクエリに複数のスロットを割り当てると、そのクエリはすべてのスロットのメモリにアクセスできます。クエリのスロットを一時的に増やす方法の詳細については、「wlm_query_slot_count」を参照してください。
十分最適でない WHERE 句
WHERE 句により実行されるテーブルスキャンが多すぎる場合、SCAN ステップのセグメントの SVL_QUERY_SUMMARY 内の maxtime
値が最も大きくなる可能性があります。詳細については、「SVL_QUERY_SUMMARY ビューの使用」を参照してください。
この問題を修正するには、最も大きいテーブルのプライマリソート列に基づいて WHERE 句をクエリに追加します。この方法により、スキャン時間を最小限に抑えることができます。詳細については、「Amazon Redshift テーブル設計のベストプラクティス」を参照してください。
述語の制限が不十分
制限が不十分な述語がクエリにある場合、SVL_QUERY_SUMMARY にある maxtime
値が最も大きいセグメントの SCAN ステップの rows
値が、クエリ内の最後の RETURN ステップにある rows
値と比較してかなり大きくなることがあります。詳細については、「SVL_QUERY_SUMMARY ビューの使用」を参照してください。
この問題を修正するには、クエリに述語を追加するか、既存の述語の制限を強めて出力を絞り込んでみてください。
非常に大きな結果セット
クエリにより非常に大きな結果セットが返される場合、UNLOADを使用して Amazon S3 に結果が書き込まれるようにクエリを書き換えることを検討してください。この方法を実行すると、並列処理を活用することで RETURN ステップのパフォーマンスが向上します。非常に大きな結果セットを確認する方法の詳細については、「SVL_QUERY_SUMMARY ビューの使用」を参照してください。
大きい SELECT リスト
クエリに非常に大きい SELECT リストがある場合、SVL_QUERY_SUMMARY 内のいずれかのステップの bytes
値が rows
値より大きくなる (他のステップと比較して) ことがあります。bytes
値が大きいことは、多くの列を選択していることを示す場合があります。詳細については、「SVL_QUERY_SUMMARY ビューの使用」を参照してください。
この問題を修正するには、選択している列を確認し、削除ができるかどうかを調べます。