

S3 Tablesの隠しパーティション、設計不要って意味じゃなかった
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
S3 TablesでAthenaからIcebergテーブルを触ってると、ドキュメントにこう書いてある。
Iceberg テーブルでは隠しパーティション化が使用されるため、物理パーティションを直接操作する必要はありません。
出典: Iceberg テーブルに対して他の DDL オペレーションを実行する - Amazon Athena
最初読んだとき「あ、パーティション設計自体もう気にしなくていいのか」と思ったんだけど、それは誤読だった。S3 Tablesに絞って整理する。
隠しパーティションが指してるもの
Hive形式だと、パーティションはS3上のディレクトリで管理される。
s3://bucket/table/ year=2025/ month=07/S3 Tablesのテーブルはこれをテーブルメタデータ側で持つ。なのでクエリを書く側は物理フォルダを意識しなくていい。
SELECT *FROM eventsWHERE event_time >= DATE '2025-07-01';Athenaのクエリエンジンがメタデータを見て不要なファイルをスキップする。これがHidden Partitioning。
ドキュメントが言ってるのは「DDLが不要」の方
上の引用が言ってるのは、Hive的な物理パーティション操作(DDL)が不要という意味。S3 Tablesのテーブルに対しても、以下のDDLはそもそもサポート対象外になってる。
SHOW PARTITIONS;ALTER TABLE ADD PARTITION ...;ALTER TABLE DROP PARTITION ...;ALTER TABLE RENAME PARTITION ...;パーティション情報を見たい場合は、SHOW PARTITIONSの代わりにメタデータテーブルを使う。
SELECT * FROM "table_name$partitions";Partition Specは普通に効いてくる
S3 TablesのIcebergテーブルにもPartition Specという概念がある。
days(event_time)hours(event_time)bucket(16, user_id)truncate(8, tenant_id)データ量が増えるほど、このSpecの選び方がクエリ性能・スキャン量・Athenaの料金・ファイルレイアウトに直接効いてくる。特に WHERE event_time BETWEEN ... や WHERE tenant_id = ... みたいな絞り込みが多いテーブルほど、設計の価値は大きい。
パーティションを後から追加したい場合
AthenaでALTER TABLE ... ADD PARTITION FIELDを実行すると、S3 Tablesでもエラーになる。
ALTER TABLE tbl_s3tables ADD PARTITION FIELD boolean_column;
-- 出力line 1:34: mismatched input 'PARTITION'. Expecting: '.', 'ADD'Partition Evolution自体はIcebergの仕様として存在するけど、Athena SQLでは実行できない。実際にやるにはGlue Studioノートブックなど、Spark経由でS3 Tablesカタログにアクセスする必要がある。
spark.sql(f"ALTER TABLE glue_catalog.{database}.{table} ADD PARTITION FIELD boolean_column")Sparkからなら成功する。
パーティション追加後、既存データはどうなるか
ここが一番勘違いしやすいところ。Partition Specを変えても、既存データは自動的に並び替わらない。
Sparkでパーティションフィールドを追加した直後にメタデータを見ると、既存行は新しいフィールドの値がnullのまま。新規にINSERTした行だけが新しいパーティションに乗る。既存データの再振り分けは実行されない。
既存データも新Specに揃えたい場合の制約
汎用S3バケット上のIcebergテーブルなら、CREATE TABLE AS(CTAS)で新しいパーティション定義のテーブルを作り直せる。
CREATE TABLE tbl_ctasWITH ( format = 'parquet', table_type = 'ICEBERG', partitioning = ARRAY['string_column', 'year(timestamp_column)', 'boolean_column']) ASSELECT * FROM tbl_gp;ただしS3 Tablesのカタログでは、このCTASがそもそもサポートされていない。
CREATE TABLE tbl_s3tables_ctasWITH ( table_type = 'iceberg', partitioning = ARRAY['string_column', 'year(timestamp_column)', 'boolean_column']) ASSELECT * FROM tbl_s3tables;
-- 出力Queries of this type: CREATE_TABLE_AS_SELECT, are not supported for this catalogつまりS3 Tablesで既存データも新しいパーティションレイアウトに揃えたい場合、CTASという逃げ道は使えない。SparkでのRewrite/Compactionなど、別の再配置手段を検討する必要がある。
まとめると
- S3 Tablesの「物理パーティション操作不要」はHive的なDDL操作が不要という意味で、設計不要という意味ではない
- Partition Specは依然として性能・コストに直結する
- パーティション追加(Partition Evolution)はAthena SQLではできず、Spark経由でS3 Tablesカタログに対して実行する
- 追加後も既存データはそのまま使えるが、自動で新レイアウトには揃わない
- 汎用S3バケット上のIcebergテーブルと違い、S3 TablesではCTASによる再作成という手段が使えない