

# タイムスタンプデータを使用する
<a name="data-types-timestamps"></a>

このセクションでは、Athena でのタイムスタンプデータを使用する場合のいくつかの考慮事項について説明します。

**注記**  
以前のエンジンバージョンから Athena エンジンバージョン 3 では、タイムスタンプの処理が多少変わりました。Athena エンジンバージョン 3 で発生する可能性のあるタイムスタンプ関連のエラーと推奨される解決策については、[Athena エンジンバージョン 3](engine-versions-reference-0003.md) リファレンスにある「[タイムスタンプの変更](engine-versions-reference-0003.md#engine-versions-reference-0003-timestamp-changes)」を参照してください。

## タイムスタンプデータを Amazon S3 オブジェクトに書き込むためのフォーマット
<a name="data-types-timestamps-writing-to-s3-objects"></a>

タイムスタンプデータを Amazon S3 オブジェクトに書き込む際の形式は、使用する列データ型と [SerDe ライブラリ](https://docs.aws.amazon.com/athena/latest/ug/supported-serdes.html)の両方によって決まります。
+ タイプ `DATE` のテーブル列がある場合、Athena はデータの対応する列またはプロパティが ISO 形式 `YYYY-MM-DD` の文字列、または Parquet や ORC のような組み込みの日付型であることを期待します。
+ タイプ `TIME` のテーブル列がある場合、Athena はデータの対応する列またはプロパティが ISO 形式 `HH:MM:SS` の文字列、または Parquet や ORC のような組み込みの時間型であることを期待します。
+ タイプ `TIMESTAMP` のテーブル列がある場合、、Athena はデータの対応する列またはプロパティが、その形式 `YYYY-MM-DD HH:MM:SS.SSS` の文字列 (日付と時刻の間のスペースに注意)、または Parquet、ORC、Ion のような組み込みの時間型であることを期待します。Athena は、無効なタイムスタンプの動作を保証しないことに注意してください (例: `0000-00-00 08:00:00.000`）。
**注記**  
OpenCSVSerDe のタイムスタンプは例外であり、ミリ秒単位の精度の UNIX エポックとしてエンコードする必要があります。

## 時間分割されたデータがレコードのタイムスタンプフィールドと一致することを確認します
<a name="data-types-timestamps-time-partitioned-data-and-timestamp-fields"></a>

データの作成者は、パーティションの値がパーティション内のデータと一致していることを確認する必要があります。たとえば、データに `timestamp` プロパティがあり、Firehose を使用してデータを Amazon S3 にロードする場合、Firehose のデフォルトパーティショニングは実経過時間ベースであることから、[動的パーティショニング](https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html)を使用する必要があります。

## パーティションキーのデータ型として文字列を使用
<a name="data-types-timestamps-partition-key-types"></a>

パフォーマンス上の理由から、パーティションキーのデータ型として `STRING` を使用することをお勧めします。Athena では `DATE` タイプを使用した場合、その形式 `YYYY-MM-DD` のパーティション値を日付として認識しますが、これによってパフォーマンスが低下する可能性があります。この理由から、パーティションキーには `STRING` データ型を使用することをお勧めします。

## 同じく時間分割されているタイムスタンプフィールドのクエリを作成する方法
<a name="data-types-timestamps-how-to-write-queries-for-timestamp-fields-that-are-also-time-partitioned"></a>

時間分割されたタイムスタンプフィールドのクエリを作成する方法は、クエリするテーブルの種類によって異なります。

### Hive テーブル
<a name="data-types-timestamps-hive-tables"></a>

Athena で最も一般的に使用されている Hive テーブルでは、クエリエンジンは列とパーティションキーの関係を認識しません。このため、クエリには必ず列とパーティションキーの両方に述語を追加する必要があります。

たとえば、`event_time` 列と `event_date` パーティションキーがあり、23:00 から 03:00 までのイベントをクエリしたいとします。この場合、次の例のように、クエリに列とパーティションキーの両方に述語を含める必要があります。

```
WHERE event_time BETWEEN start_time AND end_time 
  AND event_date BETWEEN start_time_date AND end_time_date
```

### Iceberg テーブルの使用
<a name="data-types-timestamps-iceberg-tables"></a>

Iceberg テーブルでは、計算されたパーティション値を使用できるため、クエリが簡単になります。たとえば、Iceberg テーブルが次のような `PARTITIONED BY` 句で作成されたとします。

```
PARTITIONED BY (event_date month(event_time))
```

この場合、クエリエンジンは `event_time` 述語の値に基づいてパーティションを自動的に削除します。このため、クエリでは次の例のように `event_time` の述語を指定するだけです。

```
WHERE event_time BETWEEN start_time AND end_time
```

詳細については、「[Iceberg テーブルを作成する](querying-iceberg-creating-tables.md)」を参照してください。

タイムスタンプ列に Iceberg の非表示パーティショニングを使用する場合、Iceberg はタイムスタンプ列から派生し、より効果的なパーティショニングのために日付に変換された構築済みテーブル列にパーティションを作成することがあります。例えば、タイムスタンプ列 `event_time` から `event_date` を作成し、`event_date` で自動的にパーティション分割する場合があります。この場合、パーティション**タイプ**は**日付**です。

パーティションを使用する際の最適なクエリパフォーマンスを得るには、1 日の範囲をフィルタリングして述語プッシュダウンを有効にします。例えば、次のクエリはプッシュダウンされません。範囲は 1 日以内であっても 1 つの日付パーティションに変換できないためです。

```
WHERE event_time >= TIMESTAMP '2024-04-18 00:00:00' AND event_time < TIMESTAMP '2024-04-18 12:00:00'
```

代わりに、次の例のように、1 日の範囲を使用して、述語プッシュダウンを許可し、クエリパフォーマンスを向上させます。

```
WHERE event_time >= TIMESTAMP '2024-04-18 00:00:00' AND event_time < TIMESTAMP '2024-04-19 00:00:00'
```

タイムスタンプ部分が `00:00:00` である限り、`BETWEEN start_time AND end_time` 構文を使用するか、複数日の範囲を使用することもできます。

詳細については、[Trino ブログの投稿記事](https://trino.io/blog/2023/04/11/date-predicates.html)を参照してください。