

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon Redshift クエリの設計のベストプラクティス
<a name="best-practices-designing-queries"></a>

このセクションでは、クエリの設計に関するベストプラクティスの概要を説明します。最適なクエリのパフォーマンスと効率性を実現するには、このセクションのベストプラクティスに従うことをお勧めします。

## SELECT \* FROM ステートメントを使用しない
<a name="select-from-statement"></a>

`SELECT * FROM` ステートメントは使用しないことをお勧めします。代わりに、分析する列を必ず一覧表示してください。これにより、クエリの実行時間が短縮され、Amazon Redshift Spectrum クエリのスキャンコストが削減されます。

**避けるべき内容の例**

```
select * 
from sales;
```

**ベストプラクティスの例**

```
select sales_date, sales_amt
from sales;
```

## クエリの問題を特定する
<a name="query-issues"></a>

[STL\_ALERT\_EVENT\_LOG](https://docs.aws.amazon.com/redshift/latest/dg/r_STL_ALERT_EVENT_LOG.html) ビューを確認し、クエリで発生する可能性のある問題を特定して修正することをお勧めします。

## クエリの概要情報を取得する
<a name="summary-info"></a>

クエリの概要情報を取得するには、[SVL\_QUERY\_SUMMARY](https://docs.aws.amazon.com/redshift/latest/dg/r_SVL_QUERY_SUMMARY.html) ビューと [SVL\_QUERY\_REPORT](https://docs.aws.amazon.com/redshift/latest/dg/r_SVL_QUERY_REPORT.html) ビューを使用することをお勧めします。この情報を使用して、クエリを最適化できます。

## クロス結合を避ける
<a name="cross-joins"></a>

やむを得ない場合を除き、クロス結合を使用することは避けてください。クロス結合は、2 つのテーブルの直積集合を算出する結合条件のない結合です。クロス結合は通常ネステッドループ結合として実行されますが、これは使用可能な結合タイプで最も低速な結合です。

**避けるべき内容の例**

```
select c.c_name, 
          n.n_name 
from tpch.customer c, 
        tpch.nation n;
```

**ベストプラクティスの例**

```
select c.c_name, 
           n.n_name 
from tpch.customer c, 
join tpch.nation n
  on n.n_nationkey = c.c_nationkey;
```

## クエリ述語で関数を使用しない
<a name="functions-query-predicates"></a>

クエリ述語では関数を使用しないことをお勧めします。通常、関数は各行に処理オーバーヘッドを追加し、クエリの実行全体を遅くするため、クエリ述語で関数を使用すると、パフォーマンスに悪影響を及ぼす可能性があります。

**避けるべき内容の例**

```
select sum(o_totalprice)
from tpch.orders
where datepart(year, o_orderdate) = 1992;
```

**ベストプラクティスの例**

```
select sum(o_totalprice)
from tpch.orders
where o_orderdate between '1992-01-01' and '1992-12-31';
```

## 不要なキャスト変換を避ける
<a name="cast-conversions"></a>

データ型のキャストには時間とリソースがかかり、クエリの実行が遅くなるため、クエリで不要なキャスト変換を使用しないことをお勧めします。

**避けるべき内容の例**

```
select sum(o_totalprice)
from tpch.orders
where o_ordertime::date = '1992-01-01';
```

**ベストプラクティスの例**

```
select sum(o_totalprice)
from tpch.orders
where o_ordertime between '1992-01-01 00:00:00' and '1992-12-31 23:59:59';
```

## 複雑な集計には CASE 式を使用する
<a name="case-expressions"></a>

同じテーブルから複数回選択するのではなく、[CASE 式](https://docs.aws.amazon.com/redshift/latest/dg/r_CASE_function.html)を使用して複雑な集計を実行することをお勧めします。

**避けるべき内容の例**

```
select sum(sales_amt) as us_sales
from sales
where country = 'US';

select sum(sales_amt) as ca_sales
from sales
where country = 'CA';
```

**ベストプラクティスの例**

```
select sum(case when country = 'US' then sales_amt end) as us_sales,
           sum(case when country = 'CA' then sales_amt end) as ca_sales
from sales;
```

## サブクエリを使用する
<a name="subqueries"></a>

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

**避けるべき内容の例**

サブクエリが 200 行未満を返す場合:

```
select sum(order_amt) as total_sales
from sales
where region_key IN
        (select region_key
         from regions
         where state = 'CA');
```

**ベストプラクティスの例**

サブクエリが 200 行以上を返す場合:

```
select sum(o.order_amt) as total_sales
from sales o
join regions r
  on r.region_key = o.region_key
  and r.state = 'CA';
```

## 述語を使用する
<a name="predicates"></a>

述語を使用してデータセットをできるだけ制限することをお勧めします。述語は SQL で使用され、クエリで返されるデータをフィルタリングおよび制限します。述語で条件を指定することで、指定された条件に基づいてクエリ結果に含める必要がある行を指定できます。これにより、関心のあるデータのみを取得でき、クエリの効率と精度が向上します。詳細については、Amazon Redshift ドキュメントの「[Conditions](https://docs.aws.amazon.com/redshift/latest/dg/r_conditions.html)」を参照してください。

## 述語を追加して結合を使用するテーブルをフィルタリングする
<a name="filter-tables-joins"></a>

述語が同じフィルタを適用する場合でも、述語を追加して結合に関与するテーブルをフィルタリングすることをお勧めします。述語を使用して SQL で結合を使用するテーブルをフィルタリングすると、処理する必要があるデータの量と中間結果セットのサイズを減らして、クエリのパフォーマンスを向上させることができます。`WHERE` 句で結合オペレーションの条件を指定することで、クエリ実行エンジンは、結合前に条件に一致しない行を削除できます。これにより、結果セットが小さくなり、クエリの実行が高速化されます。

**避けるべき内容の例**

```
select p.product_name, sum(o.order_amt)
from sales o
join product p
   on r.product_key = o.product_key
where o.order_date > '2022-01-01';
```

**ベストプラクティスの例**

```
select p.product_name, sum(o.order_amt)
from sales o
join product p
  on p.product_key = o.product_key
  and p.added_date > '2022-01-01'
where o.order_date > '2022-01-01';
```

## 述語には最も安価な演算子を使用する
<a name="least-expensive-operators"></a>

述語では、できる限りコストのかからない演算子を使用します。[比較条件](https://docs.aws.amazon.com/redshift/latest/dg/r_comparison_condition.html)演算子は [LIKE](https://docs.aws.amazon.com/redshift/latest/dg/r_patternmatching_condition_like.html) 演算子よりも優先されます。`LIKE` 演算子は、[SIMILAR TO](https://docs.aws.amazon.com/redshift/latest/dg/pattern-matching-conditions-similar-to.html) 演算子または [POSIX](https://docs.aws.amazon.com/redshift/latest/dg/pattern-matching-conditions-posix.html) 演算子よりも優先されます。

## GROUP BY 句でソートキーを使用する
<a name="group-by-clauses"></a>

`GROUP BY` 句でソートキーを使用すると、クエリプランナーがより効率的な集計を使用できます。`GROUP BY` リストにソートキー列のみが含まれており、そのうち 1 つが分散キーでもある場合、クエリは 1 フェーズ集計の対象となる可能性があります。`GROUP BY` リストのソートキー列には、1 番目のソートキーの後に、ソートキー順序で使用する他のソートキーが含まれている必要があります。

## マテリアライズドビューの利点
<a name="materialized-views"></a>

可能であれば、複雑なコードをマテリアライズドビューに置き換えてクエリを書き換えます。これにより、クエリのパフォーマンスが大幅に向上します。詳細については、Amazon Redshift のドキュメントの「[Amazon Redshift でのマテリアライズドビューの作成](https://docs.aws.amazon.com/redshift/latest/dg/materialized-view-overview.html)」を参照してください。

## GROUP BY 句と ORDER BY 句の列に注意する
<a name="group-by-order-by"></a>

`ORDER BY` 句と `GROUP BY` 句の両方を使用する場合は、列を `GROUP BY` 句と `ORDER BY` 句の両方に同じ順序で配置してください。`GROUP BY` では、データを暗黙的にソートする必要があります。`ORDER BY` 句が異なる場合は、データを 2 回ソートする必要があります。

**避けるべき内容の例**

```
select a, b, c, sum(d)
from a_table
group by b, c, a
order by a, b, c
```

**ベストプラクティスの例**

```
select a, b, c, sum(d)
from a_table
group by a, b, c
order by a, b, c
```