【AWS】Redshift Spectrum使い方まとめ

# はじめに

**Redshift Spectrum**は、S3を始めとした各種ストレージサービスに対して、[Redshift](https://docs.aws.amazon.com/ja_jp/redshift/index.html)によるクエリを実現するサービスです。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-using-spectrum.html

ざっくり言うと、「**S3に保存したCSV等のデータにRedshiftでクエリ実行できるサービス**」と呼べ、両者、すなわちデータレイクとDWHの良いとこ取りをできるサービスと呼べるでしょう。

一方で比較的新しいサービスである事から、日本語の記事は充実しているとは言えない状況です。そこで今回、その**操作法を簡潔にまとめ**たいと思います。

## Redshift Spectrumの特徴

Redshift Spectrumを利用するメリットとして、Redshiftを既に利用しているのであれば既存のクエリ等の資産を活用できることが挙げられます。また類似サービスである（共に[AWS Glueデータカタログ](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/catalog-and-crawler.html)を通じてS3にアクセスする）[**Amazon Athena**](https://qiita.com/c60evaporator/items/2695f0ceeccbbda1bac9)**と比較**して、**高負荷時の安定性**に[分があるようです](https://www.integrate.io/jp/blog/amazon-redshift-spectrum-vs-athena-a-detailed-comparison-ja/)。

また、DWHである**Redshift**との使い分けですが、[こちらの記事](https://dev.classmethod.jp/articles/amazon-redshift-spectrum-migration-from-amazon-redshift/)で述べられているように、

- 大容量で参照頻度の少ないテーブル: Redshift Spectrumに移行
- 参照頻度の多いテーブル: ETL等の過去の資産活用やパフォーマンスの観点から、引き続きRedshiftのテーブルを使用

と使い分けると良さそうです。

なお**Redshift Spectrumとその他のS3へのクエリサービス（データレイクサービス）との比較**は、**以下の記事**を参照ください

https://qiita.com/c60evaporator/items/f6c3a2aa1ba04618fe5e

# 前準備

Redshift Spectrumを使用するために必要な環境を構築します。

## 使用するデータ

本記事では、[こちらの記事で取得した](https://qiita.com/c60evaporator/items/92d0ebde001f568f2707)IoTデータを、年ごとにフォルダ分けし、月ごとにCSVファイルにまとめて以下のフォルダ構成 (プレフィックス)でS3バケットに格納して使用します。

なお、Redshift Spectrumでは[後ほど作成する](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ1-amazon-redshiftクラスターの作成)**Redshiftクラスター**と**S3バケット**を[**同じリージョンに設置する必要**](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-getting-started-using-spectrum.html#c-getting-started-using-spectrum-prerequisites)があるのでご注意ください。

実際の使用時は、好きなCSVファイルやテキストファイルをバケット内に格納してください。ただし[詳細はパーティションの項で解説](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#コスト削減施策2-パーティション分割)しますが、**Redshift Spectrumを使用するS3バケット**は年、月、日、時のように**時間を表すフォルダで分ける**と都合が良いです。

```
バケット名
  └──sensors
      └──per_month
          ├─2020
          │   ├─202008.csv
          │   :
          │   └─202012.csv
          ├─2021
          │   ├─202101.csv
          │   :
          │   └─202012.csv
          └─2022
              ├─202101.csv
              :
              └─202008.csv
```

コンソールでの表示例

![スクリーンショット 2023-03-19 2.09.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/2fcb4117-730d-7568-60bd-432f2e4fe886.png)

CSVファイルの中身は以下のようになっています ([参考](https://qiita.com/c60evaporator/items/92d0ebde001f568f2707#スキーマの作成))

```csv:使用するCSVファイル
_id,Date_Master,Date_ScanStart,no01_DeviceName,no01_Date,no01_Temperature,no01_Humidity,no01_Light,no01_Human_last,no01_HumanMotion,no01_TempSetting,no01_AirconMode,no01_AirVolume,no01_AirDirection,no01_AirconPower,no01_CumulativeEnergy,no01_Watt,no02_DeviceName,no02_Date,no02_Temperature,no02_Humidity,no02_Light,no02_Pressure,no02_Noise,no02_eTVOC,no02_eCO2,no03_DeviceName,no03_Date,no03_Temperature,no03_Humidity,no04_DeviceName,no04_Date,no04_Temperature,no04_Humidity,no05_DeviceName,no05_Date,no05_Temperature,no05_Humidity,no05_Light,no05_UV,no05_Pressure,no05_Noise,no05_BatteryVoltage,no06_DeviceName,no06_Date,no06_Temperature,no06_Humidity,no07_DeviceName,no07_Date,no07_Temperature,no07_Humidity,no07_BatteryVoltage,no08_DeviceName,no08_Date,no08_HumanLast,no08_HumanMotion,_partition
5f359f60de55bc0802637080,2020-08-14 05:15:00.000,2020-08-14 05:15:03.891,Nature_Remo_1,2020-08-14 05:15:06.167,28.2,64.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.17,548.0,Omron_USB_1,2020-08-14 05:15:07.093,27.48,71.54,111,1005.229,58.29,289,1650,Inkbird_IBSTH1_1,2020-08-14 05:15:10.068,27.91,68.21,Inkbird_IBSTH1_2,2020-08-14 05:15:12.706,31.49,63.15,Omron_BAG_1,2020-08-14 05:15:17.748,32.18,62.48,6.0,0.01,1006.3,39.8,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:15:21.384,26.53,75.28,SwitchBot_Thermo_1,2020-08-14 05:15:26.413,31.7,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:15:28.835,2020-08-13T20:14:14.000Z,1,Project HomeIoT
5f35a09092376c3d5d76612c,2020-08-14 05:20:00.000,2020-08-14 05:20:04.054,Nature_Remo_1,2020-08-14 05:20:06.294,28.2,62.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.22,360.0,Omron_USB_1,2020-08-14 05:20:07.249,27.45,68.86,108,1005.284,46.18,280,1638,Inkbird_IBSTH1_1,2020-08-14 05:20:12.872,27.93,66.46,Inkbird_IBSTH1_2,2020-08-14 05:20:17.417,31.4,63.06,Omron_BAG_1,2020-08-14 05:20:22.446,32.24,62.63,13.0,0.02,1006.3,38.61,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:20:25.224,26.51,74.69,SwitchBot_Thermo_1,2020-08-14 05:20:30.252,31.9,64.0,100.0,Sony_MeshHuman_1,2020-08-14 05:20:32.635,2020-08-13T20:20:14.000Z,1,Project HomeIoT
5f35a1ba291e40c5ea258ee3,2020-08-14 05:25:00.000,2020-08-14 05:25:04.460,Nature_Remo_1,2020-08-14 05:25:06.701,28.2,64.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.25,580.0,Omron_USB_1,2020-08-14 05:25:07.458,27.32,70.51,106,1005.352,44.38,259,1615,Inkbird_IBSTH1_1,2020-08-14 05:25:09.629,27.95,68.14,Inkbird_IBSTH1_2,2020-08-14 05:25:11.219,31.4,62.94,Omron_BAG_1,2020-08-14 05:25:21.290,32.15,62.87,25.0,0.03,1006.3,39.02,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:25:23.063,26.53,73.39,SwitchBot_Thermo_1,2020-08-14 05:25:28.090,31.8,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:25:30.343,2020-08-13T20:24:14.000Z,1,Project HomeIoT
5f35a2e24098c6e9f618daa4,2020-08-14 05:30:00.000,2020-08-14 05:30:03.594,Nature_Remo_1,2020-08-14 05:30:05.794,28.2,64.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.29,428.0,Omron_USB_1,2020-08-14 05:30:06.555,27.25,73.02,106,1005.377,43.66,265,1623,Inkbird_IBSTH1_1,2020-08-14 05:30:09.387,27.92,68.94,Inkbird_IBSTH1_2,2020-08-14 05:30:12.162,31.49,62.93,Omron_BAG_1,2020-08-14 05:30:17.203,32.14,62.77,32.0,0.02,1006.5,39.22,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:30:18.825,26.53,75.26,SwitchBot_Thermo_1,2020-08-14 05:30:23.865,31.7,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:30:26.573,2020-08-13T20:30:15.000Z,1,Project HomeIoT
5f35a41a90393b85364a6c71,2020-08-14 05:35:00.000,2020-08-14 05:35:04.370,Nature_Remo_1,2020-08-14 05:35:06.617,28.2,64.0,143.0,2020-08-13T20:34:01Z,1.0,28.0,cool,1,auto,power-on,2957.32,456.0,Omron_USB_1,2020-08-14 05:35:07.443,27.45,74.21,104,1005.468,57.8,244,1598,Inkbird_IBSTH1_1,2020-08-14 05:35:10.129,28.07,69.8,Inkbird_IBSTH1_2,2020-08-14 05:35:12.960,31.47,62.75,Omron_BAG_1,2020-08-14 05:35:18.000,32.06,62.93,48.0,0.02,1006.6,39.22,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:35:25.717,26.62,76.67,SwitchBot_Thermo_1,2020-08-14 05:35:35.787,31.7,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:35:38.204,2020-08-13T20:34:15.000Z,1,Project HomeIoT
:
```

## アクセス権限の付与（1. コンソール操作用）

Redshift Spectrumを使用するためには、適切なアクセス権限をIAMで作成して付与する必要があります。

注意点として、Redshift Spectrumでは**以下の2種類の権限を別個に作成**する必要があります

1. コンソール操作用
2. Redshiftクラスタへのアタッチ用

本節では「1. Redshift Spcetrumの操作用」について解説するので、「2. Redshiftクラスタへのアタッチ用」は[後の節](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#アクセス権限の付与2-redshiftクラスタへのアタッチ用)を参照してください

### IAMポリシーの作成

コンソールには、以下2種類のポリシーを付与します

A. Redshift自体の操作権限: 既存の`AmazonRedshiftFullAccess`ポリシーを使用
B. Redshiftクラスターに「2. Redshiftクラスタへのアタッチ用」ロールをアタッチする権限

このうちBに相当する権限はデフォルトのポリシー（AWS管理ポリシー）には存在しないので、[こちら](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ec2へのロールのアタッチ-管理者権限を持たないユーザから実施する場合)と同様の手順で`PassRoleToRedshift`ポリシーとして**自作**します

まずは必要なデータソース（S3およびGlue）へのアクセス権限を持ったIAMポリシーを作成します

管理者ユーザーでログインして、コンソールからIAM画面に入り、
左側のタブから「ポリシー」→「ポリシーの作成」をクリックします

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0990bac4-640f-4e77-1c78-ba2fdeec3de7.png">

「JSON」タブをクリックし、JSONでの編集モードに入ります

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c60cbcd6-dbf2-2a9d-1fac-57944eec2eaf.png">

以下のようなポリシーを記述します

```json:作成するポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPassRoleOnlyRedshift",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::アカウントIDの12桁数字:role/*",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "redshift.amazonaws.com"
                }
            }
        },
        {
            "Sid": "AllowListRoles",
            "Effect": "Allow",
            "Action": "iam:ListRoles",
            "Resource": "*"
        }
    ]
}
```

名前と説明を記載し、「ポリシーの作成」をクリックすれば作成完了です。


### IAMユーザーの作成

上記ポリシーを付与するためのIAMユーザを作成します。
管理者ユーザーでログインして、コンソールからIAM → ユーザーと進み、「ユーザを追加」をクリックします

![スクリーンショット 2021-11-27 18.29.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/6718429c-9cea-7361-bdb0-277fd1564c31.png)

好きなユーザ名とパスワードを入力し、以下のようにユーザーを作成します

![スクリーンショット 2023-03-21 23.14.28 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0e16fbca-66be-a8ff-1acf-0650ff416908.png)

先ほど作成した`PassRoleToRedshift`ポリシーおよび既存の`AmazonRedshiftFullAccess`ポリシーをアタッチします
（[後述のPython SDKからのアクセス](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#python-sdkからの使用法)を使用する場合は、EC2やVPCの操作も必要となるので`AmazonEC2FullAccess`ポリシーもアタッチしてください）

![スクリーンショット 2023-03-22 0.28.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/994e0adc-5d29-0ed8-5954-dd224ec0f5f6.png)

このユーザーでログインすることで、コンソールからRedshift Spectrumの設定に必要な操作が可能となります。
（大人数で運用する場合はユーザーに直接ポリシーをアタッチするよりもグループを使用するのが望ましいので、[こちら](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iam設定手順)をご参照ください）

## アクセス権限の付与（2. Redshiftクラスタへのアタッチ用）

### IAMポリシーの作成

まずは必要なデータソース（S3およびGlue）へのアクセス権限を持ったIAMポリシーを作成します

管理者ユーザーでログインして、コンソールからIAM画面に入り、
左側のタブから「ポリシー」→「ポリシーの作成」をクリックします

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0990bac4-640f-4e77-1c78-ba2fdeec3de7.png">

「JSON」タブをクリックし、JSONでの編集モードに入ります

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c60cbcd6-dbf2-2a9d-1fac-57944eec2eaf.png">

以下のようなポリシーを記述します
（例えば、`RedshiftSpectrumPolicy`というポリシー名を付けます。`"Resource"`の部分を`"*"`から対象のバケットのみに絞るとセキュリティ強度がさらに強まりますが、利便性とのバランスで判断してください）

```json:作成するRedshiftSpectrumPolicyポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListMultipartUploadParts",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "glue:CreateDatabase",
                "glue:DeleteDatabase",
                "glue:GetDatabase",
                "glue:GetDatabases",
                "glue:UpdateDatabase",
                "glue:CreateTable",
                "glue:DeleteTable",
                "glue:BatchDeleteTable",
                "glue:UpdateTable",
                "glue:GetTable",
                "glue:GetTables",
                "glue:BatchCreatePartition",
                "glue:CreatePartition",
                "glue:DeletePartition",
                "glue:BatchDeletePartition",
                "glue:UpdatePartition",
                "glue:GetPartition",
                "glue:GetPartitions",
                "glue:BatchGetPartition"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

名前と説明を記載し、「ポリシーの作成」をクリックすれば作成完了です。

### ロールの作成
Redshift Spectrum用のロール（[後ほどRedshiftクラスタにアタッチ](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ2-iamロールをクラスターと関連付ける)）を作成します。

IAMの左側のタブから「ロール」 → 「ロールを作成」をクリックします

<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/b58a4e56-134f-8b93-7be3-0e9db52640d3.png">

- 信頼されたエンティティタイプ: AWSのサービス
- ユースケース: Redshift → Redshift - Customizable
を選択します。

![スクリーンショット 2023-04-01 22.41.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/30b56f22-f475-9a32-a7ac-02e898875a8f.png)

先ほど作成した`RedshiftSpectrumPolicy`をチェックして「次へ」を押します

![スクリーンショット 2023-04-01 22.46.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/53b70689-637d-defa-42cc-10c6678d2f5d.png)

ロール名と説明を記載し、「ロールを作成」をクリックするとロールの作成が完了します

![スクリーンショット 2023-04-01 22.48.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c3364f0b-ebc9-d717-5f31-d9cf6510dd3c.png)

なお、以下の作成したロールのARNは[後ほど使用する](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#外部スキーマの作成)ので、どこから閲覧できるのかを覚えておいてください

![スクリーンショット 2023-04-01 23.23.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/5674baea-ceff-bf5e-cd83-78bed1d49086.png)


# Redshift Spectrumの使用法

Redshift Spectrumは、コンソール、およびDB操作用のライブラリ（Pythonの場合Psycopg2やredshift_connector）を利用してS3内のデータをクエリする事ができます。

本記事では、このうち使用頻度が高いと思われる**コンソール**、**Pythonライブラリ**（redshift_connector）による操作方法を紹介します。

具体的には以下の手順でクエリを実行します

ステップ1: Amazon Redshiftクラスターの作成
ステップ2: IAMロールをクラスターと関連付ける
ステップ3: 外部スキーマと外部テーブルを作成する
ステップ4: Amazon S3のデータにクエリを実行する

## コンソールからの使用法

コンソールからRedshift Spectrumを使用するためには、まず以下リンクからRedshiftコンソールを開きます（AWSコンソールから"Redshift"と検索して移動してもOKです）

https://ap-northeast-1.console.aws.amazon.com/redshiftv2

### ステップ1: Amazon Redshiftクラスターの作成

Redshift Spectrumを使用するためには、まずクエリの実行基盤（EC2のようなコンピューティングを行う計算資源）となる「Redshiftクラスタ」を作成する必要があります。

左側ナビゲーションペインの「クラスター」タブ→「クラスターを作成」をクリックします

![スクリーンショット 2023-04-01 21.56.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/042c4482-41b0-ea8f-66e7-c6184260a9fd.png)

以下のようにクラスターの設定を入力し、「クラスターを作成」をクリックします

<img width=360 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/8fd76023-ab63-58dd-fc6f-45e0450cdc05.png>

<img width=360 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/ca76d4bd-1625-b9bd-25a1-e58c2bf4018d.png>

以下のノード料金を見ると分かりますが、最安のdc2.largeの1ノードでも**3万円/月以上の維持費**が掛かるので、クラスターを作ったまま放置しないようご注意ください

<img width=320 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0c34befc-a82e-4c5c-5940-46da96b00835.png>

#### ※Redshiftクラスターのネットワーク設定

VPC外にあるAthenaはIAMの権限でアクセス制御を行っていましたが、RedshiftクラスターはVPCの中に設置されるため、**適切なネットワーク設定をしなければアクセスできません**。

特に[後述のPython](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#python-sdkからの使用法)等のスクリプトからの操作時は、**スクリプトが動いているPCまたはAWS内のリソース**（EC2やLambda等）**からRedshiftクラスタにアクセスできる**よう、**VPCを適切に設定**する必要があります。

VPC設定の詳細は以下の記事を参照下さい

https://qiita.com/c60evaporator/items/2f24d4796202e8b06a77

クラスター作成時にVPC設定を変更するには、以下のように「追加設定」の「デフォルトを使用」をOFFにし、「ネットワークとセキュリティ」をクリックします

<img width=420 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/01b413e4-b4c6-6d87-0457-0f472a1a9914.png>

また、ここでグレーアウトされていて選択できないVPCも存在しますが、これはVPCにクラスターサブネットグルプが紐付けられていない事が原因です。以下を参考にサブネットグループを作成してください

https://www.youtube.com/watch?v=eJ4cmQFw_mc

### ステップ2: IAMロールをクラスターと関連付ける

[アクセス権限の付与](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#アクセス権限の付与2-redshiftクラスタへのアタッチ用)で作成したIAMロールをクラスターに付与します。
作成したクラスターをチェックしたのち、「アクション」→「IAMロールの管理」とクリックします

<img width=640 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c0c49db2-3ce1-dde5-1715-c1510454485e.png>

先ほど[「2. Redshiftクラスタへのアタッチ用」](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ロールの作成)として作成した`RedshiftSpectrumRole`ロールを選択し、「IAMロールを関連付ける」をクリックしてロールをアタッチしたのち、「変更を保存」をクリックします

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/fd14c983-4cdc-5c26-4fe5-1207efe060f7.png>

### ステップ3: 外部スキーマと外部テーブルの作成

RedshiftとS3を紐づけるための、外部スキーマと外部テーブルを作成します。

#### デフォルトデータベース名の確認

まずデフォルトのデータベース名を確認するため、作成したクラスターを以下のように確認します

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/92cdd33b-d8fa-2ffe-2cb0-e1ce43f88f8e.png>

以下の「データベース名」に記載されている名称をメモします

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c0544062-6d55-cd65-afc9-99cc231b4393.png>

基本的には`dev`となっているはずです

#### データベースの作成

次にRedshift Spectrumに使用するデータベースを作成します。

「クエリエディタ」を以下のように開き、「データベースに接続」をクリックします

![スクリーンショット 2023-04-02 20.37.50 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c4bee78a-e0d8-66c6-92eb-a4e3e4092704.png)

以下のようにデフォルトデータベース名を管理者ユーザー名を入力し、「接続」をクリックします

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/30112a81-0528-392e-6028-24a4b1710396.png>

クエリエディタに戻り、以下のようにデフォルトデータベースを選択します

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/e1c2f9e1-4e3e-acff-d39d-614fd0de419b.png>

クエリエディタの以下の赤枠部分に、

![スクリーンショット 2023-04-02 20.37.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/ee4ee75c-55ae-6c4b-291a-767841b03e09.png)

以下のようなクエリ文を記載して、「実行する」をクリックします

```sql
create database 好きなデータベース名
```

以下の「接続を変更」をクリックし、作成したデータベース名と管理者ユーザー名を入力して「接続」をクリックします

![スクリーンショット 2023-04-02 21.38.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0e4c5c70-7e3b-eba5-4a0f-e8ce19179e3c.png)

#### 外部スキーマの作成

クエリエディタで以下のクエリ文を実行し、外部スキーマを作成します。

```sql
create external schema myspectrum_schema 
from data catalog 
database '作成したデータベース名' 
iam_role '先ほど控えたRedshiftSpectrumRoleロールのARN'
create external database if not exists;
```

※上記の`myspectrum_schema`がスキーマ名に相当するので、適宜変更してください。

以下のように「リソース」の「Select schema」で作成したスキーマを選択します

![スクリーンショット 2023-04-02 21.44.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/e8bb170b-9d10-03c1-0997-dcf0e58189b4.png)

#### 外部テーブルの作成

S3バケットとRedshift Spectrumを結び付けるための「テーブル」を作成します。

テーブルと結びつくのは基本的にS3バケット内のフォルダ（プレフィックス）となり、テーブルを作成すればフォルダ内のファイル全てに一括でクエリを実行する事ができます。

クエリエディタから以下のようなコマンドを実行することで、テーブルを作成できます。

```sql:テーブルを作成するクエリ
create external table スキーマ名.テーブル名(
カラム名1 型名1,
カラム名2 型名2,
:
中略
:
)
row format delimited
fields terminated by 'フィールドの区切り文字'
lines terminated by 'レコードの改行文字'
stored as ファイル形式
location 's3://バケット名/プレフィックス/'
table properties (各種プロパティを記載);
```

指定できる型の種類やファイル形式、プロパティ等の詳細は、[こちらの公式ドキュメント](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html)を参照ください。

例えば、[先ほど紹介したサンプルバケット](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#使用するデータ)の`per_month`フォルダをテーブルの作成対象とする場合、フィールドの区切り文字は`','`（カンマ）、レコードの改行文字は`'\n'`、プレフィックスは`sensors/per_month/`となるので、以下のようなコマンドでテーブルを作成できます。
（テーブル名は"sample_table1"とします。また必ずしもファイル内の全ての列名を指定する必要はなく、一部の列のみ指定する事もできるので、今回はno01の列のみ選択します）

```sql:テーブルを作成するクエリの例
create external table myspectrum_schema.sample_table1(
_id varchar(100),
Date_Master timestamp,
Date_ScanStart timestamp,
no01_DeviceName varchar(100),
no01_Date timestamp,
no01_Temperature real,
no01_Humidity real,
no01_Light real,
no01_Human_last varchar(100),
no01_HumanMotion real,
no01_TempSetting real,
no01_AirconMode varchar(100),
no01_AirVolume varchar(100),
no01_AirDirection varchar(100),
no01_AirconPower varchar(100),
no01_CumulativeEnergy real,
no01_Watt real
)
row format delimited
fields terminated by ','
lines terminated by '\n'
stored as textfile
location 's3://バケット名/sensors/per_month/'
table properties ('skip.header.line.count'='1');
```

※よくある注意点

- `row format delimited`の部分は、直後に`lines terminated by`と`lines terminated by`を記述することで区切り文字を指定します。`row format serde`とするとより複雑な指定も可能になるので、詳細は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html)を参照ください
- フィールドの区切り文字がタブの場合、`fields terminated by '\t'`と指定します。
- `table properties ('skip.header.line.count'='1')`は、1行目をヘッダ行として読み飛ばすことを表します。1行目がヘッダ行でない場合は削除してください
- CSVやtxtファイルの場合`stored as textfile`を、Parquetファイルの場合、`stored as PARQUET`を指定してください

作成がうまくいくと、以下のように「クエリ結果」に`Completed`と表示されます

<img width=400 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/17ea421e-5929-fe56-53d4-02473c5204fa.png>

上記でクエリを実行する準備は完了ですが、Redshiftの操作に管理者ユーザー（IAMのAdministratorユーザーではなくデータベースの管理者ユーザーです）を使用しており、セキュリティ的に強固とは言えない状況なので、適宜`CREATE USER`クエリでユーザーを作成し、`GRANT`で必要な権限を付与してください。

### ステップ4: Amazon S3のデータにクエリを実行する

ここまでで前準備が完了し、ここから実際にクエリを実行してS3からデータを取得する事ができます。

プラス (+) 記号をクリックして新しいクエリタブを開き、クエリペインに好きなSQL文を打ちます。例えば全ての列を取得したい場合は、以下のようにアスタリスク(*)を使用します（データ数が多い場合、[料金](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#redshift-spectrumの料金)に注意してください）

```sql
select * from スキーマ名.テーブル名
```

実行例

```sql
select * from myspectrum_schema.sample_table1;
```

実行結果

```
_id,date_master,date_scanstart,no01_devicename,no01_date,no01_temperature,no01_humidity,no01_light,no01_human_last,no01_humanmotion,no01_tempsetting,no01_airconmode,no01_airvolume,no01_airdirection,no01_airconpower,no01_cumulativeenergy,no01_watt
61cf1b102f31e88b3f5b52ec,2022-01-01 00:00:00,2022-01-01 00:00:03.903,Nature_Remo_1,2022-01-01 00:00:05.675,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.91015625,160
61cf1c3d62228317200da710,2022-01-01 00:05:00,2022-01-01 00:05:03.759,Nature_Remo_1,2022-01-01 00:05:05.55,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.919921875,164
61cf1d695b33f11da52488c9,2022-01-01 00:10:00,2022-01-01 00:10:04.195,Nature_Remo_1,2022-01-01 00:10:06.021,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.93017578125,104
61cf1e98ba1ed7ee918b34df,2022-01-01 00:15:00,2022-01-01 00:15:04.267,Nature_Remo_1,2022-01-01 00:15:06.084,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.93994140625,104
61cf1fbd0e1be80d78b28300,2022-01-01 00:20:00,2022-01-01 00:20:03.691,Nature_Remo_1,2022-01-01 00:20:05.483,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.9501953125,108
61cf20f5d8b9f629c41a30db,2022-01-01 00:25:00,2022-01-01 00:25:04.099,Nature_Remo_1,2022-01-01 00:25:05.908,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.9599609375,112
61cf2216d5a7b17f7c09f1d5,2022-01-01 00:30:00,2022-01-01 00:30:04.163,Nature_Remo_1,2022-01-01 00:30:05.952,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.97021484375,108
61cf23491bd95b0313e124ff,2022-01-01 00:35:00,2022-01-01 00:35:03.699,Nature_Remo_1,2022-01-01 00:35:05.448,11.600000381469727,29,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.97998046875,104
61cf247136ac51ab9d9e630e,2022-01-01 00:40:00,2022-01-01 00:40:03.719,Nature_Remo_1,2022-01-01 00:40:05.516,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5962.990234375,108
61cf259db6405e0b8211a79d,2022-01-01 00:45:00,2022-01-01 00:45:03.907,Nature_Remo_1,2022-01-01 00:45:05.682,14,32,8,2021-12-28T00:19:41Z,0,22,warm,auto,auto,power-off,5963,112
:
```

Redshift Spectrumの**クエリの文法**は基本的に**Redshiftに準拠**するので、詳細は以下のSQLコマンドを参照ください

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_SQL_commands.html

ここではいくつかの例を紹介します。

列に対してフィルタを指定したい場合は、以下のようにWHERE文を使用できます

```sql
select Date_Master, no01_Temperature, no01_AirconPower from myspectrum_schema.sample_table1
where no01_Temperature > 28.5 and no01_AirconPower = 'power-on'
```

```:実行結果
date_master,no01_temperature,no01_airconpower
2020-08-14 13:35:00,30,power-on
2020-08-14 13:40:00,30,power-on
2020-08-14 13:45:00,30,power-on
2020-08-14 13:50:00,30,power-on
2020-08-14 13:55:00,29.400001525878906,power-on
:
```

ORDER BYやGROUP BYによる集計も可能です

```sql:ORDER BYの例
select Date_Master, no01_Temperature, no01_AirconPower from myspectrum_schema.sample_table1
where no01_Temperature > 28.5 AND no01_AirconPower = 'power-on'
order by Date_Master
```

```:実行結果
date_master,no01_temperature,no01_airconpower
2020-08-14 13:35:00,30,power-on
2020-08-14 13:40:00,30,power-on
2020-08-14 13:45:00,30,power-on
2020-08-14 13:50:00,30,power-on
2020-08-14 13:55:00,29.400001525878906,power-on
```

```sql:GROUP BY集計の例
select no01_AirconPower, avg(no01_Temperature) from myspectrum_schema.sample_table1
group by no01_AirconPower
```

```:実行結果
no01_airconpower,avg
,
power-on_maybe,26.0373967091073
power-off,22.986347120465346
power-on,24.321050247798734
```

## Python SDKからの使用法

Redshiftは代表的なRDBMSであるPostgreSQLがベースとなったDBのため、多くのPythonのDB操作用パッケージ、例えばPsycopg2やSQLAlchemy等で操作する事が可能です。
よってRedshiftの基盤を用いるRedshift Spectrumも。多くのDB操作用パッケージからの接続が可能です。

本記事では、以下の公式ドキュメントで紹介されている**Amazon Redshift Pythonコネクタ**（redshift_connector）**を通じてRedshift Spectrumを操作する方法**を紹介します

https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/python-redshift-driver.html

PythonからRedshift Spectrumを操作するためには、**事前にコンソールから**「[**ステップ1. Amazon Redshiftクラスターの作成**](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ1-amazon-redshiftクラスターの作成)」「[**ステップ2: IAMロールをクラスターと関連付ける**](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ2-iamロールをクラスターと関連付ける)」「[**ステップ3: 外部スキーマと外部テーブルを作成する**](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ3-外部スキーマと外部テーブルの作成)」**を実行**しておく必要があります。

### PythonによるRedshift接続のための前準備

上記に加えて、以下の前準備も必要となります。

- Amazon Redshift Pythonコネクタのインストール
- Redshiftクラスタへのネットワーク疎通確保
- ホスト情報とポート番号の確認

それぞれ解説します

#### Amazon Redshift Pythonコネクタのインストール

Amazon Redshift Pythonコネクタ（redshift_connector）をインストールします。

pipを使用する場合、以下コマンドでインストールできます

```bash
pip install redshift_connector
```

condaを使用する場合、以下コマンドでインストールできます

```bash
conda install -c conda-forge redshift_connector
```

#### Redshiftクラスタへのネットワーク疎通確保

[Redshiftクラスターのネットワーク設定](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#redshiftクラスターのネットワーク設定)で前述したように、RedshiftクラスタはVPCの中に設置されるため、そのままでは外部から接続できません。

Pythonスクリプトが動いているPCまたはAWS内のリソース（EC2やLambda等）からアクセスできるよう、**クラスター作成時のVPCの設定**を変更する必要があります。

今回は、Redshiftクラスターと同じVPC内にEC2インスタンスを作成し、そこでPythonスクリプトを動作させる事とします。

最低限必要なアクセス許可として、以下のようにRedshiftクラスタの所属するセキュリティグループに、EC2インスタンスの所属するセキュリティグループからのRedshift用ポートへの通信許可を追加します。

![スクリーンショット 2023-04-05 1.27.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3b0991b8-5665-cf5e-b91c-f50488558723.png)

その他のVPC設定は、以下の記事をご参照ください。

https://qiita.com/c60evaporator/items/2f24d4796202e8b06a77

#### ホスト情報とポート番号の確認

接続に必要なホスト情報を以下のように確認します

![スクリーンショット 2023-04-02 21.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/92cdd33b-d8fa-2ffe-2cb0-e1ce43f88f8e.png)

以下の「エンドポイント」に記載されている名称をメモします。

![スクリーンショット 2023-04-03 23.35.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/f2ccc77d-f23f-6708-8135-99110894c610.png)

例えば`examplecluster.abc123xyz789.us-west-1.redshift.amazonaws.com:5439/dev`と記載されていた場合、

- `examplecluster.abc123xyz789.us-west-1.redshift.amazonaws.com`の部分がホスト
- `5439`の部分がポート番号

を表します。
（`dev`の部分はデフォルトのデータベース名を表しますが、これは使用せずに実際に接続するデータベース名を指定します）

なお、"JDBC URL"、"ODBC URL"に記載されている情報も、接続するツールに応じて使用する事があります。

### スクリプト例
ここまででPythonからRedshift Spectrumに接続する準備が整いました。
ここから以下の手順でクエリを実行し、Pythonスクリプト内にデータを取得します。

1. Redshiftクラスターに接続
2. `conn.cursor()`メソッドでcursorオブジェクトを作成
3. `cursor.execute()`メソッドでクエリの実行
4. `cursor.fetch_dataframe()`メソッドでPandas DataFrameに実行結果を変換

下の例では、[コンソールでの実行例と同じクエリ](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ4-amazon-s3のデータにクエリを実行する)を実行してPandasのデータフレームに変換しています。

```athena_example.py
import redshift_connector

HOST = 'ホスト名'  # 先ほど確認したホスト名
PORT = ポート番号  # 先ほど確認したポート番号（int型）
DATABASE = 'データベース名'  # コンソールで作成したデータベース名
USER = '使用するデータベースのユーザー名'
PASSWOR = '使用するユーザーのパスワード'
SCHEMA_NAME = '外部スキーマ名'  # コンソールで作成した外部スキーマ名
TABLE_NAME = '外部テーブル名'  # コンソールで作成した外部テーブル名
COLNAMES = ['Date_Master', 'no01_Temperature', 'no01_AirconPower']  # クエリ取得対象の列名

# SQLクエリを記述
QUERY = f"select {','.join(COLNAMES)} from {SCHEMA_NAME}.{TABLE_NAME} where no01_Temperature > 28.5 and no01_AirconPower = 'power-on'"

# 1. Redshiftクラスターに接続
conn = redshift_connector.connect(
    host=HOST,
    port=PORT,
    database=DATABASE,
    user=USER,
    password=PASSWORD
)

# 2. cursorオブジェクトを作成
cursor = conn.cursor()
# 3. クエリの実行
cursor.execute(QUERY)
# 4. Pandas DataFrameに実行結果を変換
result = cursor.fetch_dataframe()
print(result)
```

```:実行結果
            date_master  no01_temperature no01_airconpower
0   2020-08-14 13:35:00         30.000000         power-on
1   2020-08-14 13:40:00         30.000000         power-on
2   2020-08-14 13:45:00         30.000000         power-on
3   2020-08-14 13:50:00         30.000000         power-on
4   2020-08-14 13:55:00         29.400002         power-on
:
```

実行してみると分かりますが、クエリ結果の行数が多い（数千行以上）場合、**Athenaより高速に動作**するので、一定規模以上のS3へのクエリをPythonスクリプトから実行したい場合、Redshift Spectrumはおすすめです。

# Redshift Spectrumの高速化

Redshift Spectrumの速度パフォーマンス向上には、以下の公式ベストプラクティスが参考になります

https://aws.amazon.com/jp/blogs/news/10-best-practices-for-amazon-redshift-spectrum/

# Redshift Spectrumの料金

Redshift Spectrumの料金は、以下の公式サイトに記載されています。

https://aws.amazon.com/jp/redshift/pricing/#Amazon_Redshift_Spectrum_pricing

2023年4月現在、東京リージョンでは以下のような料金となっています。

![スクリーンショット 2023-04-03 1.50.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/68b0c94a-291e-e757-13d9-a1711815eaaa.png)

クエリ自体の実行料金はAthenaとほぼ同額ですが、[前述のように](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ1-amazon-redshiftクラスターの作成)高額のRedshiftクラスタ料金（連続起動した場合最低で3万円/月）が乗るため、継続利用する際はご注意下さい。

## Redshift Spectrumのコスト削減施策

Redshift Spectrumのコストを削減するには、以下の公式ベストプラクティスが参考になります

https://repost.aws/ja/knowledge-center/redshift-spectrum-query-charges

基本的にはAthenaと同様に、

**1. データの圧縮**
**2. 分割（パーティション分割）**
**3. 列形式への変換**

を行うと、この「スキャンされたデータ」のサイズを減らすことができます。

またベストプラクティスに記載されているように、

**4. 同時実行スケーリング機能を使用して動的にクラスタ数を制御する**
**5. Redshift Spectrumのコストコントロール機能で使用量をモニタリングおよび制御する**

もコストコントロールにおいて有効です。

それぞれ解説します。

### コスト削減施策1: データの圧縮

S3に保存するデータを圧縮形式（GZIP等）にすると、スキャン対象のデータサイズを減らす事ができ、コスト削減に繋がります。

### コスト削減施策2: パーティション分割

データを Apache Hive スタイルで**パーティション分割**することで、スキャン対象のデータサイズを減らす事ができ、**パフォーマンス向上＆コスト削減**に繋がります。

**パーティションの分割単位**として、一般的には**年、月、日、時間等の時系列**がよく用いられます。
[こちらの記事](https://dev.classmethod.jp/articles/athena-partition-reinvent/)のAthenaではHiveフォーマットを考慮したファイル構成としていればパーティションの分割を半自動化できますが、Redshift Spectrumにはこのような半自動化機能は見当たらず、基本的には手動でパーティションを追加する必要がありそうです。

このケースの注意点として、パーティションの分割単位を表すフォルダが存在する必要があります。すなわち、**S3へのデータの蓄積段階で月ごとや日ごとにフォルダを分けておく**必要があります。

例えば[先ほどのテーブル作成](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#外部テーブルの作成)において、年フォルダごとにパーティションを分割したい場合、

```sql:パーティションを分割してテーブルを作成するクエリの例
create external table myspectrum_schema.sample_table1(
_id varchar(100),
Date_Master timestamp,
Date_ScanStart timestamp,
no01_DeviceName varchar(100),
no01_Date timestamp,
no01_Temperature real,
no01_Humidity real,
no01_Light real,
no01_Human_last varchar(100),
no01_HumanMotion real,
no01_TempSetting real,
no01_AirconMode varchar(100),
no01_AirVolume varchar(100),
no01_AirDirection varchar(100),
no01_AirconPower varchar(100),
no01_CumulativeEnergy real,
no01_Watt real
)
partitioned by (partition_year integer(10))
row format delimited
fields terminated by ','
lines terminated by '\n'
stored as textfile
location 's3://バケット名/sensors/per_month/'
table properties ('skip.header.line.count'='1');
```

というように、`partitioned by (パーティション列名 型名)`で指定します（パーティション列名は好きな新規列名を指定します）

テーブルが作成されたら、パーティション追加のために以下のクエリも実行する必要があります

```sql:フォルダをパーティションに指定する
alter table myspectrum_schema.sample_table1 add partition(partition_year='2020')
location 's3://iot-backup-data/sensors/per_month/2020/'
partition(partition_year='2021')
location 's3://iot-backup-data/sensors/per_month/2021/'
partition(partition_year='2022')
location 's3://iot-backup-data/sensors/per_month/2022/'
```

上記クエリを全てのパーティションについて手動実行する必要があるので、日毎に分割する場合のように分割数が多いケースでは骨が折れます（[先ほどの](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#スクリプト例)Python SDK等を使ってクエリの実行を自動化すると良いでしょう）

以下のように、パーティション列名でwhere文を実行することで、スキャン対象のデータサイズを削減する事ができます

```sql:パーティションを指定したクエリ
select * from myspectrum_schema.sample_table1
where partition_year='2022'
```

パーティション分割の詳細は以下の公式ドキュメントを参照ください。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-spectrum-external-tables.html#c-spectrum-external-tables-partitioning

### コスト削減施策3: データの列形式への変換

S3に保存するデータをCSVではなく列指向のParquet形式にすると、SELECT文で指定した列のみが「スキャンされたデータ」に、クエリの工夫次第で大幅にコストを削減する事ができます。

列指向形式のデータでコスト（および処理時間）を削減したい場合、

```sql
select * from 外部スキーマ名.外部テーブル名
```

のようにアスタリスクで全列を取得するのではなく、

```sql
select 列名1, 列名2 from 外部スキーマ名.外部テーブル名
```

のように列名を具体的に指定し、**必要な列のみを取得**するようにしてください

また、CSV等をParquet形式に変換する方法は以下の公式ドキュメントを参照ください。

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/convert-to-columnar.html

### コスト削減施策4: 同時実行スケーリング機能を使用して動的にクラスタ数を制御する

[前述のように](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#ステップ1-amazon-redshiftクラスターの作成)、Redshift Spectrumでは料金の多くを高額のクラスタ月額料金が占めます。よって起動するクラスタの数を必要最低限に保つことが、コスト削減に寄与します。

この要件を実現するため、クエリの実行数が多い時のみ一時的にクラスターを追加する、**同時実行スケーリング機能**（Concurrency Scaling）と呼ばれる機能が存在します。これにより普段は必要最低限のクラスターのみ起動しておき、必要な時のみ自動でクラスターを増やす事ができます。

同時実行スケーリングの詳細は以下の記事が分かりやすいです。

https://dev.classmethod.jp/articles/20190329-amazon-redshift-concurrency-scaling-benchmark/

同時実行スケーリングは、以下のように「ワークロード管理」から設定する事ができます。

<img width=720 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c28d41a6-7030-a8fd-cfdf-941d1ec22b02.png>

<img width=640 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3a9d634c-48d0-444b-b89a-91209a1efbd8.png>

また同時実行スケーリングに使用制限を設け、使いすぎを防ぐこともできます。
スケーリングの使用制限は以下の手順で設定できます。

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/bd73b850-1fc1-4d4b-9193-360bd742725c.png>

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/177c7466-d296-bd9d-c129-e3d3e039ec66.png>


### コスト削減施策5: Redshift Spectrumのコストコントロール機能で使用量をモニタリングおよび制御する

クエリの使用量が一定の容量に達したら、特定のアクション（SNSによるアラートの発報、ログの記録、機能の無効化）を実行する機能が存在します。
これにより、使いすぎに気づいたり防止したりする事ができます。

この機能は以下の「Redshift Spectrumの使用制限」から設定する事ができます。

<img width=480 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/bd73b850-1fc1-4d4b-9193-360bd742725c.png>

<img width=400 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/01a38045-5410-4aef-d716-2e21c77bf744.png>