

 Amazon Redshift は、パッチ 198 以降、新しい Python UDF の作成をサポートしなくなります。既存の Python UDF は、2026 年 6 月 30 日まで引き続き機能します。詳細については、[ブログ記事](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)を参照してください。

# テーブルのバキューム処理
<a name="t_Reclaiming_storage_space202"></a>

Amazon Redshift は、バックグラウンドでテーブルを自動でソートし、VACUUM DELETE オペレーションを実行できます。ロードまたは一連の増分更新の後にテーブルをクリーンアップするには、データベース全体または個々のテーブルに対して [VACUUM](r_VACUUM_command.md) コマンドを実行することもできます。

**注記**  
必要なテーブルのアクセス許可を持つユーザーのみが、テーブルのバキューム処理を効果的に行うことができます。必要なテーブルアクセス許可なしで VACUUM が実行された場合、オペレーションは完了しますが、効果はありません。バキューム処理を効果的に実行するための有効なテーブルのアクセス許可のリストについては、「[VACUUM](r_VACUUM_command.md)」を参照してください。  
このため、必要に応じて、テーブルを個別にバキューム処理することをお勧めします。この方法をお勧めするもう 1 つの理由は、データベース全体をバキューム処理すると、コストのかかるオペレーションになる場合があるからです。

## 自動テーブルソート
<a name="automatic-table-sort"></a>

Amazon Redshift は、データをバックグラウンドで自動的にソートし、テーブルデータをソートキー順に維持します。Amazon Redshift は、スキャンクエリを追跡し、テーブルのどのセクションがソートする利点あるかを判断します。Amazon Redshift は、同時実行スケーリングクラスターからのスキャンクエリも追跡します。Amazon Redshift データ共有を使用するマルチクラスターアーキテクチャの場合、Amazon Redshift は、異なるリージョンのクラスター/ワークグループを含む、データメッシュ内のコンシューマークラスター/ワークグループから発生するスキャンクエリも追跡します。メインクラスター、同時実行スケーリングクラスター、コンシューマークラスターからのスキャン統計が集約され、テーブルのどのセクションがソートの恩恵を受けるかが決まります。

システムの負荷に応じて、Amazon Redshift は自動でソートを開始します。この自動ソートにより、データをソートキー順に維持するために VACUUM コマンドを実行する必要が少なくなります。例えば、大きなデータをロードした後に、ソートキー順でデータを完全にソートする必要がある場合でも、VACUUM コマンドを手動で実行することができます。VACUUM SORT コマンドの実行が有効的かどうかを判断するには、`vacuum_sort_benefit`の[SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)をモニタします。

Amazon Redshift は、各テーブルのソートキーを使用するスキャンクエリを追跡します。Amazon Redshift は、テーブルが完全にソートされている場合、各テーブルのデータのスキャンやフィルターの最大改善率を見積ります。この見積もりは、`vacuum_sort_benefit`の[SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)列で表示されます。この列は、`unsorted`列と一緒に使用することができ、クエリの際、いつテーブルで VACUUM SORT を手動で実行したら効率的かを判断します。`unsorted`列は、テーブルの物理的なソート順を反映しています。`vacuum_sort_benefit` 列は、VACUUM SORT を手動で実行することでソートによるテーブルへの影響を特定します。

例えば、次のクエリを考えてみます。

```
select "table", unsorted,vacuum_sort_benefit from svv_table_info order by 1;
```

```
 table | unsorted | vacuum_sort_benefit 
-------+----------+---------------------
 sales |    85.71 |                5.00
 event |    45.24 |               67.00
```

「sales」というテーブルの場合、86% が物理的にソートされていなくても、86% ソートされていないテーブルからのクエリ実行の影響は、5% だけとなります。理由としては、クエリがテーブルの一部にしかアクセスしていないか、ごく少数のクエリがテーブルにアクセスしたかのどちらかとなります。「event」というテーブルの場合、テーブルは、45% が物理的にソートされていません。ですが、67% のクエリ実行の影響は、クエリがテーブルの大部分にアクセスしたか、テーブルにアクセスしたクエリが多かったことを表しています。「event」というテーブルには、VACUUM SORT の実行が潜在的に有効となります。

## 自動バキューム削除
<a name="automatic-table-delete"></a>

削除を実行すると、行は削除対象としてマークされますが、削除されません。Amazon Redshift は、データベーステーブルの削除された行数に基づいて、バックグラウンドで VACUUM DELETE オペレーションを自動的に実行します。Amazon Redshift では、負荷が軽減されているときに VACUUM DELETE を実行するようにスケジュールし、負荷が高いときにはオペレーションを一時停止します。

**Topics**
+ [自動テーブルソート](#automatic-table-sort)
+ [自動バキューム削除](#automatic-table-delete)
+ [VACUUM の頻度](#vacuum-frequency)
+ [ソートステージとマージステージ](#vacuum-stages)
+ [バキュームのしきい値](#vacuum-sort-threshold)
+ [バキュームの種類](#vacuum-types)
+ [バキューム処理時間の最小化](vacuum-managing-vacuum-times.md)

## VACUUM の頻度
<a name="vacuum-frequency"></a>

一貫性のあるクエリパフォーマンスを維持するために、必要な頻度でバキューム処理を実行する必要があります。VACUUM コマンドの実行頻度を決めるときは、これらの要因を考慮します。
+ VACUUM は、夜間や指定されたデータベース管理期間など、クラスターのアクティビティが最小限になると予想される期間に実行します。
+ メンテナンスウィンドウ以外で VACUUM コマンドを実行します。詳細については、「[保守時間の時間枠を回避したスケジュール計画](https://docs.aws.amazon.com/redshift/latest/dg/c_best-practices-avoid-maintenance.html)」を参照してください。
+ 大きなリージョンが未ソートの状態であれば、バキューム処理の時間が長くなります。バキューム処理を遅らせる場合、再整理しなければならないデータが増えるのでバキューム処理にかかる時間が長くなります。
+ VACUUM は I/O 集約型な操作です。そのため、バキューム処理の完了にかかる時間が長ければ、同時クエリとクラスターで実行されている他のデータベース操作に与える影響が大きくなります。
+ VACUUM は、インターリーブソートを使用するテーブルに対しては時間がかかります。インターリーブテーブルを再ソートする必要があるかどうかを評価するには、[SVV\$1INTERLEAVED\$1COLUMNS](r_SVV_INTERLEAVED_COLUMNS.md) ビューのクエリを実行します。

## ソートステージとマージステージ
<a name="vacuum-stages"></a>

Amazon Redshift では、2 つのステージでバキュームオペレーションを実行します。最初に未ソートのリージョン内の行をソートし、続いて必要に応じて、テーブルの最後の新しくソートされた行に既存の行をマージします。大きなテーブルでバキュームを実行すると、バキューム操作は一連の差分ソートから成るステップを実行した後で、マージを実行します。オペレーションが失敗した場合、または Amazon Redshift がバキュームの間にオフラインになった場合は、部分的にバキュームが実行されたテーブルまたはデータベースは一貫性のある状態が保たれますが、バキュームオペレーションを手動で再開する必要があります。差分ソートは失われますが、操作が失敗する前にコミットされたマージ済みの行に再度バキューム処理を実行する必要はありません。未ソートのリージョンが大きい場合は、無駄になる時間が大きくなる可能性があります。ソートとマージのステージの詳細については、「[マージ済みの行のボリューム管理](vacuum-managing-vacuum-times.md#vacuum-managing-volume-of-unmerged-rows)」を参照してください。

ユーザーは、バキューム処理中のテーブルにアクセスできます。バキューム処理中のテーブルにクエリおよび書き込み操作を実行できますが、DML およびバキュームを同時に実行すると両方の処理時間が長くなる可能性があります。バキューム処理中に UPDATE および DELETE ステートメントを実行する場合は、システムのパフォーマンスが低減する場合があります。差分マージにより UPDATE と DELETE の同時操作が一時的にブロックされ、UPDATE と DELETE により操作で影響のあるテーブルでのマージのステップが一時的にブロックされます。ALTER TABLE などの DDL 操作は、テーブルでバキューム操作が終了するまでブロックされます。

**注記**  
VACUUM の様々な修飾子により、その動作方法が制御されます。それらを使用して、現在のニーズに合わせてバキュームオペレーションを調整することができます。例えば、VACUUM RECLUSTER を使用すると、完全なマージ操作が実行されないので、バキューム操作が短縮されます。詳細については、「[VACUUM](r_VACUUM_command.md)」を参照してください。

## バキュームのしきい値
<a name="vacuum-sort-threshold"></a>

デフォルトではVACUUM コマンドで、テーブルの行の 95 パーセント以上がすでにソートされているテーブルのソートフェーズをスキップします。ソートフェーズをスキップすることにより、VACUUM のパフォーマンスが大幅に向上します。VACUUM コマンドを実行するとき、テーブル名および TO *threshold* PERCENT パラメータを含む 1 つのテーブルの、デフォルトのソートしきい値を変更する。

## バキュームの種類
<a name="vacuum-types"></a>

バキュームのタイプ別の詳細については、「[VACUUM](r_VACUUM_command.md)」を参照してください。

# バキューム処理時間の最小化
<a name="vacuum-managing-vacuum-times"></a>

 Amazon Redshift は、背景で自動的にデータをソートし、VACUUM DELETE を実行します。これにより、VACUUM コマンドを実行する必要が少なくなります。バキューム処理は時間がかかる可能性があります。データの特性に応じて、バキューム処理時間を最小化するために、以下のプラクティスをお勧めします。

**Topics**
+ [インデックスを再生成するかどうかの決定](#r_vacuum-decide-whether-to-reindex)
+ [未ソートリージョンのサイズを管理する](#r_vacuum_diskspacereqs)
+ [マージ済みの行のボリューム管理](#vacuum-managing-volume-of-unmerged-rows)
+ [ソートキー順序でデータをロードする](#vacuum-load-in-sort-key-order)
+ [時系列テーブルを使用して保存データを削減する](#vacuum-time-series-tables)

## インデックスを再生成するかどうかの決定
<a name="r_vacuum-decide-whether-to-reindex"></a>

多くの場合、インターリーブソート方式を使用することで、クエリのパフォーマンスを大幅に向上させることができますが、時間の経過とともに、ソートキー列の値の分散が変わった場合、パフォーマンス低下につながることがあります。

最初に COPY または CREATE TABLE AS を使用して空のインターリーブテーブルをロードすると、Amazon Redshift は自動的にインターリーブインデックスを構築します。最初に INSERT を使用してインターリーブテーブルをロードする場合は、その後に VACUUM REINDEX を実行して、インターリーブインデックスを初期化する必要があります。

時間の経過と共に、新しいソートキー値を持つ行を追加するにつれて、ソートキー列の値の分布が変更されると、パフォーマンスが低下する可能性があります。新しい行が既存のソートキー値の範囲内に主に存在する場合、インデックスを再作成する必要はありません。VACUUM SORT ONLY あるいは VACUUM FULL を実行して、ソート順序を復元します。

クエリエンジンはソート順を使用して、クエリの処理用にスキャンする必要のあるデータブロックを効率的に選択できます。インターリーブソートの場合、Amazon Redshift はソートキー列の値を分析して、最適なソート順を決定します。行が追加されて、キー値の分散が変わった、つまりスキューが発生した場合、ソート方法は最適でなくなり、ソートのパフォーマンス低下につながります。ソートキーの分散を再分析するには、VACUUM REINDEX を実行できます。REINDEX オペレーションには時間がかかるため、テーブルに対してインデックスの再生成が有効かどうかを決定するには、[SVV\$1INTERLEAVED\$1COLUMNS](r_SVV_INTERLEAVED_COLUMNS.md) ビューのクエリを実行します。

例えば、以下のクエリを実行すると、インターリーブソートキーを使用するテーブルについて詳細が表示されます。

```
select tbl as tbl_id, stv_tbl_perm.name as table_name, 
col, interleaved_skew, last_reindex
from svv_interleaved_columns, stv_tbl_perm
where svv_interleaved_columns.tbl = stv_tbl_perm.id
and interleaved_skew is not null;


 tbl_id | table_name | col | interleaved_skew | last_reindex
--------+------------+-----+------------------+--------------------
 100048 | customer   |   0 |             3.65 | 2015-04-22 22:05:45
 100068 | lineorder  |   1 |             2.65 | 2015-04-22 22:05:45
 100072 | part       |   0 |             1.65 | 2015-04-22 22:05:45
 100077 | supplier   |   1 |             1.00 | 2015-04-22 22:05:45
(4 rows)
```

`interleaved_skew` の値はスキューの量を示す比率です。値が 1 の場合、スキューがないことを意味します。スキューが 1.4 よりも大きい場合、基とするセットからのスキューでなければ、VACUUM REINDEX により通常はパフォーマンスが向上します。

`last_reindex` で日付値を使用して、前回のインデックス再生成から経過した時間を調べることができます。

## 未ソートリージョンのサイズを管理する
<a name="r_vacuum_diskspacereqs"></a>

データがすでに含まれているテーブルに大量の新しいデータをロードするか、定期的な保守管理操作の一環としてテーブルのバキューム処理を実行しないとき、未ソートのリージョンが増えます。長時間のバキューム操作を避けるために、以下の手法を利用できます。
+ 定期的なスケジュールでバキューム操作を実行します。

  (テーブルの合計行数の少ないパーセンテージを表す毎日の更新など) 少ない増分でテーブルをロードする場合、VACUUM を定期的に実行すると、個別のバキューム操作が短時間で終了します。
+ 最も大きなロードを最初に実行します。

  複数の COPY 操作で新しいテーブルをロードする必要がある場合、最も大きなロードを最初に実行します。新しいテーブルまたはTRUNCATE されたテーブルに初回ロードを実行すると、すべてのデータがソート済みリージョンに直接ロードされます。そのため、バキュームは必要ありません。
+ すべての行を削除するのではなく、テーブルの全データを削除します (Truncate)。

  テーブルから行を削除した場合、その行が占有していた領域はバキューム操作を実行するまで再利用されません。ただし、テーブルの全データを削除した（Truncate）場合、テーブルが空になり、ディスク領域が再利用されます。そのため、バキュームは必要ありません。または、テーブルを削除し (Drop)、再作成します。
+ テストテーブルの全データを削除するか、テーブル自体を削除します。

  テスト目的で少ない数の行をテーブルにロードする場合、完了時に行を削除しないでください。代わりに、テーブルの全データを削除し、後続の本稼働のロード操作の一環としてこれらの行を再ロードします。
+ ディープコピーを実行します。

  複合ソートキーテーブルを使用するテーブルにソートされていない大きなリージョンがある場合、ディープコピーがバキュームよりずっと高速です。ディープコピーでは、一括挿入を使用してテーブルが再作成され、再設定されます。これにより、テーブルが自動的に再ソートされます。テーブルにソートされていない大規模なリージョンがある場合、ディープコピーの方がバキューム処理より高速です。欠点としては、ディープコピー処理中は同時更新を実行できません。バキューム処理では実行できます。詳細については、「[Amazon Redshift クエリの設計のベストプラクティス](c_designing-queries-best-practices.md)」を参照してください。

## マージ済みの行のボリューム管理
<a name="vacuum-managing-volume-of-unmerged-rows"></a>

バキューム操作で新しい行をテーブルのソート済みリージョンにマージする必要がある場合、バキュームに必要な時間はテーブルが大きくなるにつれて長くなります。マージが必要な行の数を少なくすると、バキュームのパフォーマンスが向上します。

バキューム処理前のテーブルは、最初にソート済みリージョン、その後ろに未ソートのリージョンで構成され、未ソート領域は行の追加または更新が行われると大きくなります。COPY 操作で行のセットが追加された場合、新しい行のセットは、テーブルの最後の未ソート領域に追加されたときにソートキーでソートされます。新しい行は、未ソートリージョン内ではなく固有のセット内で順序付けされます。

次の図は、2 つの連続する COPY 操作後の未ソートのリージョンを示しています。ソートキーは CUSTID です。分かりやすいように、この例では複合ソートキーを示していますが、インターリーブテーブルにより未ソートリージョンの影響が大きくならなければ、同じ原則はインターリーブソートキーにも当てはまります。

![\[2 つの COPY オペレーションからのレコードを保持するソートされていないテーブル。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-unsorted-region.png)


バキュームにより、2 つのステージでテーブルのソート順が元に戻ります。

1. 未ソートのリージョンを新しくソートされたリージョンにソートします。

   最初のステージでは未ソートのリージョンのみが書き換えられるため、比較的低コストです。新しくソートされたリージョンのソートキーの値の範囲が既存の範囲を超えた場合、新しい行のみを書き換える必要があり、バキュームは完了します。例えば、ソート済みリージョンに 1～500 の ID 値が含まれ、それ以降のコピーオペレーションで追加されたキーの値が 500 を超えた場合は、未ソートのリージョンのみを書き換える必要があります。

1. 新しくソートされたリージョンと前にソートされたリージョンをマージします。

   新しくソートされたリージョンのキーとソート済みリージョンのキーが重複する場合は、VACUUM で行をマージする必要があります。新しくソートされたリージョンの先頭から開始すると (最も低いソートキーで)、バキュームにより、前にソートされたリージョンおよび新しくソートされたリージョンからマージされた行が新しいブロックのセットに書き込まれます。

新しいソートキーの範囲と既存のソートキーが重複する範囲により、再度書き込む必要のあるソート済みリージョンの範囲が決まります。未ソートのキーが既存のソート範囲全体に分散する場合は、バキュームにより、テーブルの既存部分を再度書き込む必要があります。

次の図は、テーブルに追加された行をバキュームによってソートおよびマージする方法を示しています。CUSTID はソートキーです。各コピー操作により、既存のキーと重複するキー値を持つ新しい行セットが追加されるため、テーブルのほぼ全体を再度書き込む必要があります。図に示されているのは単一のソートとマージですが、実際には、大規模なバキュームは一連の差分ソートおよびマージステップから成ります。

![\[サンプルテーブルの VACUUM オペレーションを 2 つのステップで実行します。最初に新しい行がソートされ、既存の行とマージされます。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-unsorted-region-sort-merge.png)


新しい行のセットのソートキーの範囲が既存のキーの範囲と重複する場合、マージステージのコストは、テーブルが大きくなると、テーブルサイズに比例して大きくなります。一方、ソートステージのコストは、未ソートリージョンのサイズに比例したままとなります。このような場合、次の図に示すように、マージステージのコストはソートステージのコストを上回ります。

![\[新しい行に既存の行と重複するソートキーがある場合に、マージステージがどのように高価になるかを示す図。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-example-merge-region-grows.png)


テーブルのどれだけの部分が再マージされたかを特定するには、バキューム操作が完了した後で SVV\$1VACUUM\$1SUMMARY のクエリを行います。次のクエリは、CUSTSALES が時間の経過と共に大きくなったときに、6 回連続でバキュームを実行した場合の効果を示します。

```
select * from svv_vacuum_summary
where table_name = 'custsales';


 table_name | xid  | sort_      | merge_     | elapsed_   | row_  | sortedrow_ | block_  | max_merge_
            |      | partitions | increments | time       | delta | delta      | delta   | partitions
 -----------+------+------------+------------+------------+-------+------------+---------+---------------
  custsales | 7072 |          3 |          2 |  143918314 |     0 |   88297472 |   1524  |      47
  custsales | 7122 |          3 |          3 |  164157882 |     0 |   88297472 |    772  |      47
  custsales | 7212 |          3 |          4 |  187433171 |     0 |   88297472 |    767  |      47
  custsales | 7289 |          3 |          4 |  255482945 |     0 |   88297472 |    770  |      47
  custsales | 7420 |          3 |          5 |  316583833 |     0 |   88297472 |    769  |      47
  custsales | 9007 |          3 |          6 |  306685472 |     0 |   88297472 |    772  |      47
 (6 rows)
```

merge\$1increments 列は、バキューム操作ごとにマージされたデータの量を示します。連続バキュームを超えるマージインクリメントの数がテーブルサイズの増加と比例して増えた場合は、既存のソート済みリージョンと新たにソートされるリージョンが重複するため、バキューム操作ごとにテーブル内の行数が増加して再マージされていることを示します。

## ソートキー順序でデータをロードする
<a name="vacuum-load-in-sort-key-order"></a>

COPY コマンドを使用してソートキー順序でデータをロードする場合、バキューム処理の必要性が減少するか、なくなることもあります。

COPY では、以下のすべてが該当する場合に、テーブルのソート済みリージョンに自動的に新しい行が追加されます。
+ テーブルでは、1 つのソート列のみで複合ソートキーが使用されます。
+ ソート列は NOT NULL です。
+ テーブルは 100% ソート済みであるか空です。
+ すべての新しい行は、既存の行 (削除対象としてマークされた行も含む) よりソート順が高くなっています。この場合、Amazon Redshift では、ソートキーの最初の 8 バイトを使用してソート順が決定されます。
+  COPY コマンドは、特定の負荷最適化をトリガーしません。大量のデータをロードする場合、Amazon Redshift はテーブルのソートされたリージョンに行を追加するのではなく、新しいソートされたパーティションを作成することでパフォーマンスを最適化できます。

例えば、顧客 ID と時刻を使用して顧客イベントを記録するテーブルがあるとします。顧客 ID でソートする場合は、前の例に示すとおり、差分ロードによって新たに追加された行のソートキー範囲が既存の範囲と重複し、コストの高いバキューム操作につながる可能性があります。

タイムスタンプ列にソートキーを設定する場合、新しい行は、次の図に示すとおり、テーブルの末尾にソート順で追加されるため、バキュームの必要が減少するか、なくなります。

![\[タイムスタンプ列をソートキーとして使用し、ソートが不要な新しいレコードを取得するテーブル。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-unsorted-region-date-sort.png)


## 時系列テーブルを使用して保存データを削減する
<a name="vacuum-time-series-tables"></a>

ローリング期間のデータを保持する場合は、次の図に示すとおり、一連のテーブルを使用します。

![\[5 つの四半期データを含む 5 つのテーブル。最も古いテーブルは、1 年分の推移を維持するために削除されます。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-example-unsorted-region-copy-time-series.png)


データセットを追加するたびに新しいテーブルを作成して、シリーズの最も古いテーブルを削除します。次のような二重の利点があります。
+ DROP TABLE 操作は大量の DELETE よりもはるかに効率的であるため、行を削除する余分なコストを避けることができます。
+ テーブルがタイムスタンプでソートされる場合は、バキュームは必要ではありません。各テーブルに 1 か月のデータが含まれる場合、テーブルがタイムスタンプでソートされていない場合でも、バキュームで最大でも 1 か月分のデータを再書き込みする必要があります。

レポーティングクエリで使用するために、UNION ALL ビューを作成し、データが複数のテーブルに保存されているという事実を隠すことができます。クエリがソートキーでフィルタリングされる場合は、クエリプランナーは使用されないすべてのテーブルを効率的にスキップできます。その他の種類のクエリでは UNION ALL の効率が下がる可能性があるため、テーブルを使用するすべてのクエリのコンテキストでクエリパフォーマンスを評価してください。