メニュー
Amazon Redshift
データベース開発者ガイド (API Version 2012年12月1日)

クエリパフォーマンスの向上

クエリパフォーマンスに影響を与える一般的な問題と、それらの問題を診断して解決する手順を以下に示します。

テーブル統計がないか古い

テーブル統計がないか古い場合、次の状況が発生することがあります。

  • EXPLAIN コマンドの結果として警告メッセージが表示される。

  • STL_ALERT_EVENT_LOG に統計がないことを示すアラートイベントが記録される。詳細については、「クエリアラートの確認」を参照してください。

この問題を修正するには、ANALYZE を実行します。

Nested Loop

ネステッドループがある場合、STL_ALERT_EVENT_LOG にネステッドループのアラートイベントが記録されることがあります。ネステッドループにあるクエリの特定 でクエリを実行することで、このイベントタイプを識別することもできます。詳細については、「クエリアラートの確認」を参照してください。

この問題を修正するには、クエリでクロス結合を確認し、可能であれば削除します。クロス結合は、2 つのテーブルのデカルト積を算出する結合条件のない結合です。通常、ネステッドループ結合として実行されますが、これは考えられる結合の種類の中で最も低速です。

Hash Join

ハッシュ結合が存在する場合、次の状況が発生する可能性があります。

  • クエリプランにハッシュおよびハッシュ結合操作がある。詳細については、「クエリプランの分析」を参照してください。

  • 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 にかなり限定的なアラートイベントが記録されることがあります。詳細については、「クエリアラートの確認」を参照してください。

データスキューまたは未ソート行のあるテーブルの特定 でクエリを実行することにより、クエリ内のいずれかのテーブルに未ソート領域が大量にあるかどうかを確認することもできます。

この問題を修正するには、いくつかの方法を実行することができます。

  • クエリテーブルで VACUUM を実行し、行を再ソートします。

  • クエリテーブルでソートキーを確認し、改善できる点がないかどうかを調べます。変更を加える前に、必ずこのクエリのパフォーマンスと他の重要なクエリやシステム全体のパフォーマンスを比較検討してください。詳細については、「ソートキーの選択」を参照してください。

十分最適でないデータ分散

データ分散が十分に最適でない場合、次の状況が発生する可能性があります。

  • 直列実行、大量のブロードキャスト、または大量の分散に関するアラートイベントが 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 句をクエリに追加します。この方法はスキャン時間が最小限に抑えるためにも役立ちます。詳細については、「テーブル設計のベストプラクティス」を参照してください。

述語の制限が不十分

制限が不十分な述語がクエリにある場合、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 ビューの使用」を参照してください。

この問題を修正するには、選択している列を確認し、削除ができるかどうかを調べます。