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

Amazon Redshift のクエリの設計のベストプラクティス

クエリパフォーマンスを最大化するには、クエリの作成時に次の推奨事項に従います。

  • ベストプラクティスに従ってテーブルを設計し、クエリパフォーマンスの強固な基盤を提供します。詳細については、「Amazon Redshift のテーブル設計のベストプラクティス」を参照してください。

  • select * は使用しないでください。明確に必要な列のみを含めます。

  • 同じテーブルから複数回選択するのではなく、CASE 式 を使用して複雑な集計を実行します。

  • どうしても必要でなければクロス結合を使用しないでください。これらの結合に結合条件がないと、2 つのテーブルのデカルト積が求められます。クロス結合は通常ネステッドループ結合として実行されますが、これは考えられる結合の種類の中で最も低速です。

  • クエリのテーブル 1 つが述語条件のみで使用されている場合には、サブクエリを使用します。この場合、サブクエリはわずかな数の行を返します (ほぼ 200 未満)。次の例では、LISTING テーブルへの結合を回避するためにサブクエリを使用します。

    Copy
    select sum(sales.qtysold) from sales where salesid in (select listid from listing where listtime > '2008-12-26');
  • 述語を使用してデータセットをできるだけ制限します。

  • 述語で、できる限りコストのかからない演算子を使用します。LIKE 演算子には、比較条件 演算子が推奨されます。SIMILAR TO または POSIX 演算子 には、引き続き LIKE 演算子が推奨されます。

  • クエリ述語で関数を使用しないでください。それらを使用すると、クエリの中間ステップの解決に多くの行が必要になるため、クエリのコストが上昇する可能性があります。

  • 可能な場合、データセットを制限するために、WHERE 句を使用します。次に、クエリプランナーは行の順序を使用して、条件に一致するレコードを判断できるため、多数のディスクブロックのスキャンをスキップできます。これを行わない場合、クエリ実行エンジンは該当する列を完全にスキャンする必要があります。

  • 述語が同じフィルタを適用する場合でも、述語を追加して結合に関与するテーブルをフィルタリングします。クエリは同じ結果セットを返しますが、Amazon Redshift はスキャンステップの前に結合テーブルをフィルタリングし、それらのテーブルで効率的にブロックのスキャンを省略できます。結合条件で使用された列をフィルタリングする場合、冗長フィルタは必要ありません。

    たとえば、SALESLISTING に結合して、12 月以降にリストされ、販売者別に分類されたチケットを検索するとします。両方のテーブルは日付でソートされています。次のクエリは、共通キーのテーブルを結合し、12 月 1 日より後の listing.listtime 値をフィルタリングします。

    Copy
    select listing.sellerid, sum(sales.qtysold) from sales, listing where sales.salesid = listing.listid and listing.listtime > '2008-12-01' group by 1 order by 1;

    sales.saletime の述語が WHERE 句に含まれないため、実行エンジンは SALES テーブル全体をスキャンしなければならなくなります。フィルタによって結合に関与する行が少なくなることがわかっている場合は、そのフィルタも追加します。次の例では、実行時間が大幅に減ります。

    Copy
    select listing.sellerid, sum(sales.qtysold) from sales, listing where sales.salesid = listing.listid and listing.listtime > '2008-12-01' and sales.saletime > '2008-12-01' group by 1 order by 1;
  • GROUP BY 句でソートキーを使用すると、クエリプランナーがより効率的な集計を使用できます。GROUP BY リストにソートキー列のみが含まれており、そのうち 1 つが分散キーでもある場合、クエリは 1 フェーズ集計の対象となる可能性があります。GROUP BY リストのソートキー列には、1 番目のソートキーの後に、ソートキー順序で使用する他のソートキーが含まれている必要があります。たとえば、1 番目のソートキーを使用する、1 番目と 2 番目のソートキーを使用する、1 番目、2 番目、3 番目のソートキーを使用する、などが有効です。1 番目と 3 番目のソートキーを使用することは有効ではありません。

    EXPLAIN コマンドを実行し、クエリの集計ステップで XN GroupAggregate を探すことにより、1 フェーズ集計の使用を確認できます。

  • GROUP BY 句と ORDER BY 句の両方を使用する場合、必ずどちらにも同じ順序で列を配置してください。つまり、以下の方法を使用します。

    Copy
    group by a, b, c order by a, b, c

    この方法を使用しないでください。

    Copy
    group by b, c, a order by a, b, c