同じ SQL なのに遅い、思ったより料金が高い。そんなとき、WHERE 句を足してみるだけで済ませていないでしょうか。Athena は S3 のファイルを直接読んで答えるサービスなので、速さも料金も「何を読んだか」で決まります。この記事では、Athena が S3 を読む流れと、読む量を減らす 3 つの手を整理します。基本形は データレイクとは何か で押さえた前提で進めます。
この記事の結論
- Athena はデータを自分で持たず、Glue Data Catalog のテーブル定義に従って S3 のファイルを直接読みます。
- 読む量が減るほど速くなり、スキャン量に応じた課金も小さくなります。減らす手は「フォルダーを絞る」「列を絞る」「ファイルを整える」の 3 つです。
- パーティションは S3 のパス(
dt=2026-10-14/のような key=value)で、WHERE にパーティション列を使ったときだけ効きます。 - Parquet や ORC は列ごとに圧縮して保存するため、必要な列とブロックだけを読めます。CSV や JSON からの変換は CTAS や Glue ジョブで行います。
- パーティションが増えすぎるとメタデータの取得が重くなります。そのときはパーティション射影などを検討します。
Athena はデータを持たない|S3 とカタログを読んで SQL に答える仕組みとは
Amazon Athena は、S3 に置いたデータを SQL で分析するサーバーレスのクエリサービスです。ここで大事なのは、Athena の中にデータは無い、という点です。表に見えているものは、AWS Glue の Data Catalog に登録された「定義」です。定義には、列の名前と型、そしてデータが置かれている S3 の場所が書かれています。
クエリを投げると、Athena は Data Catalog から表の定義と場所を取得し、該当する S3 のファイルを読んで結果を返します。したがって、処理の中心は「S3 からどれだけ読むか」です。料金も、単価は公式の料金ページで確認することとして、仕組みとしては読んだデータ量に応じた課金です。読む量が減れば、速くなり、安くなります。
WHERE THE DATA LIVESデータは S3 にある
Athena は持たない。カタログで場所を調べ、S3 を読む
-
SQL
クエリを投げる
-
Athena
データは持たない
-
Data Catalog
表と場所の地図
-
S3 のファイル
ここを読む
-
結果
読んだ量が決め手
Data Catalog は Athena だけのものではなく、EMR や Redshift Spectrum なども共通のメタデータストアとして参照できます。この「地図」を共通にしておくことが、後で出てくるパーティションの登録にも関わります。
パーティションとは何か|S3 のパスで「読むフォルダー」を絞る
パーティションは、データを S3 のパス(フォルダー)で分けておき、クエリが必要な分だけを読めるようにする仕組みです。たとえば日付で分けるなら、次のように置きます。
s3://example-bucket/orders/dt=2026-10-13/part-0001.parquet
s3://example-bucket/orders/dt=2026-10-14/part-0001.parquet
dt=2026-10-14 のような key=value の形は Hive 形式と呼ばれます。表の定義で dt をパーティション列にしておけば、次のクエリは該当する日のフォルダーだけを読みます。
SELECT order_id, amount
FROM orders
WHERE dt = '2026-10-14';
注意点は、絞り込みがパスの単位で効くことです。パーティション列を WHERE に使わなければ、Athena は読む場所を絞る手がかりがなく、全パーティションのファイルを読みます。ほぼすべてのクエリが日付範囲で絞られるなら、日付で分ける。よく絞り込む列で分ける、というのが基本です。
絞れている状態と、絞れていない状態
NARROW IT DOWN読む範囲
速く安くするコツは、フォルダーと列を絞ること
絞れていない
読む量が多い
- 全フォルダーを読む
- CSV で全列を読む
- WHERE にパーティション列が無い
絞れている
読む量が少ない
- 必要なフォルダーだけ読む
- Parquet で必要な列を読む
- WHERE にパーティション列がある
CHECK 1ここまでの確認
パーティション列を WHERE に使わないクエリを実行すると、どうなる?
答えと解説
答え: 2. 全パーティションのファイルを読むことになる
パーティションの絞り込みは S3 のパス(フォルダー)の単位で効きます。条件にパーティション列が無ければ、読む場所を絞る手がかりがありません。「パーティションとは何か」の章を読み直してください。
列指向形式(Parquet・ORC)はなぜスキャン量を減らせるのか
パーティションが「どのフォルダーを読むか」を絞るのに対し、列指向形式は「ファイルの中のどこを読むか」を絞ります。CSV や JSON は行ごとにデータが並ぶので、欲しい列が 1 つでも行全体を読むことになります。Apache Parquet と Apache ORC は列ごとにまとめて保存し、列単位で圧縮します。
| 観点 | CSV・JSON(行ごと) | Parquet・ORC(列指向) |
|---|---|---|
| 並び方 | 1 行ずつ全列が並ぶ | 列ごとにまとめて並ぶ |
| 100 列から 3 列だけ使う集計 | 全列を含むデータを読む | 必要な列を中心に読める |
| 圧縮 | ファイル全体に掛けることが多い | 列ごと・ブロックごとに掛かる |
| 条件による絞り込み | ファイルを読んでから判定 | ブロックの統計を見て、読まないブロックを飛ばせる |
公式ドキュメントでは、列指向形式は必要な列だけを読み、条件に合わないブロックを飛ばすこと(述語プッシュダウン)や、ファイルを分割して並列に読むことが挙げられています。列を絞る SELECT と、列指向形式がセットで効く、と覚えてください。SELECT * は列を絞れないので、形式を変えても効果が出にくくなります。
どちらを選ぶかは、複雑なクエリや Arrow 系のツールとの相性なら Parquet、複雑な型や小さなファイルなら ORC が候補です。最終的には、自分のデータで比べて決めます。
CHECK 2ここまでの確認
100 列あるデータから 3 列だけを参照する集計を繰り返すとき、読む量を減らしやすい保存形式は?
答えと解説
答え: 2. 列ごとにまとめて圧縮する Parquet などの列指向形式
列指向形式は列ごとにまとめて保存するので、参照する列だけを読めます。行ごとに並ぶ形式は、1 列だけ欲しくても行全体を読む必要があります。「列指向形式」の章を参照してください。
パーティションを登録する仕組み|MSCK REPAIR TABLE・クローラー・パーティション射影
S3 にフォルダーを足しただけでは、Athena はそれをパーティションとして知りません。表の定義(Data Catalog)に「このパーティションはこの場所にある」と登録する必要があります。主な方法は次のとおりです。
| 方法 | 向く場面 | 補足 |
|---|---|---|
MSCK REPAIR TABLE |
key=value 形式のパスをまとめて追加したい | Hive 形式のパスだけが対象 |
ALTER TABLE ADD PARTITION |
key=value 形式でないパスや、特定の場所を追加したい | 値と場所を明示して追加する |
| Glue クローラー | スキーマとパーティションを推定して登録したい | 実行して Data Catalog に登録させる |
| パーティション射影 | パーティションが非常に多い | 値と場所を設定から計算で求める |
パーティション射影は、パーティションの値と場所をテーブルプロパティの設定から計算する方法です。数十万に及ぶ大量のパーティションで、クエリの計画時にパーティション情報を取得する時間が目立つとき、また新しい時間帯の登録が追いつかないときの選択肢です。設定の書き方は、公式ドキュメントの該当ページで確認してください。
パーティションは細かいほど良いわけではありません。数が増えすぎるとメタデータの取得自体が重くなります。「よく絞る列に絞る」ことと、増えすぎたら射影を検討することを、セットで考えます。
CHECK 3ここまでの確認
パスが key=value の形になっていない S3 の場所を、パーティションとして使うにはどうする?
答えと解説
答え: 2. ALTER TABLE ADD PARTITION で場所を指定して追加する
MSCK REPAIR TABLE は key=value 形式(Hive 形式)のパスを探して追加するものです。形式が違う場合は、パーティションの値と場所を明示して追加します。「登録する仕組み」の章を読み直してください。
変換はどこでやるか|CTAS と Glue ジョブの使い分け
CSV や JSON で届いたデータを、パーティション付きの Parquet に変えるには、大きく 2 つの道があります。
- CTAS(CREATE TABLE AS SELECT): クエリの結果から新しいテーブルを作る SQL です。形式、圧縮、パーティションを 1 文で指定できます。SQL が書ければ、クラスターを用意せずに済むため、過去分の 1 回きりの変換に向きます。
- Glue ジョブ: Spark などで動くサーバーレスの ETL です。スケジュールで定期実行できるので、毎日届くデータの変換に向きます。読む側でも、プッシュダウン述語を指定すれば、パーティション列で読む場所を絞れます。
WHY SLOW OR COSTLY切り分けの順
遅い・高いときは絞れているか → 形式 → ファイルの順に見る
-
パーティションで絞れているか
WHERE にパーティション列を使う
-
列指向形式になっているか
CSV・JSON なら Parquet や ORC に変換
-
ファイルが細かすぎないか
小さなファイルが大量ならまとめて書き直す
遅い・高いときの切り分け順
遅い、高い、と感じたら、闇雲に WHERE を足さず、次の順に確かめます。
- 絞れているか: パーティション列を WHERE に使っているか。使っていなければ全パーティションを読んでいます。
- 形式は適切か: 列指向形式か。CSV や JSON のままなら、変換で読む量が減らせます。
- ファイルは細かすぎないか: 小さなファイルが大量にあると、ファイルを開く手間が増えて遅くなることがあります。まとめて書き直す方法は、公式のパフォーマンス最適化のページも参照してください。
加えて、想定外の全件スキャンを止めたい場合は、Athena のワークグループでクエリごとのデータ使用量の上限を設定できます。上限を超えたクエリは取り消されます。条件の付け忘れによる大きな請求の保険になります。
最後に、たとえ話を正確な言葉に戻します。「棚の案内を使う」がパーティションで絞ること、「目次を見て必要な章だけ読む」が列指向形式で列を絞ることです。Athena の速さと料金は、この 2 つで読む量を減らせたかどうかで、大きく変わります。
まとめ
- Athena はデータを持たず、Data Catalog の定義に従って S3 を読む。速さも料金も読む量で決まる。
- フォルダーはパーティションで、列は列指向形式で絞る。どちらも、クエリ側が絞り込みの条件を書いてこそ効く。
- 登録は MSCK REPAIR TABLE や ALTER TABLE ADD PARTITION、クローラー、射影。変換は CTAS と Glue ジョブ。
- 切り分けは「絞れているか → 形式 → ファイルの細かさ」の順。
データレイクの整え方が、生成 AI アプリの根拠データとしてどう効くかは、次の 生成 AI アプリの本番設計 で扱います。
参照ソース
- Amazon Athena ユーザーガイド「Partition your data」 — パーティションでスキャン量を絞る仕組み、Hive 形式のパス、MSCK REPAIR TABLE と ALTER TABLE ADD PARTITION、パーティション射影の説明の根拠(2026-10 時点で確認)
- Amazon Athena ユーザーガイド「Use columnar storage formats」 — Parquet と ORC の列ごとの圧縮、述語プッシュダウン、分割読み、CTAS や Glue による変換の根拠(2026-10 時点で確認)


