Amazon Web Services ブログ

Amazon Athena がクエリ実行のオブザーバビリティを高めるシステムテーブルを導入

本記事は 2026 年 11 月 9 日 に公開された「Amazon Athena introduces system tables for query execution observability」を翻訳したものです。

多くの方が Amazon Athena でデータレイク全体に SQL クエリを実行し、対話型の分析から定期実行のレポートパイプラインまで、幅広い処理に活用しています。ただし、ワークロードの状況を十分に把握できていないことも少なくありません。ユーザー、ワークグループ、クエリが増えて Athena の利用が広がるにつれ、どのクエリのコストが高いのか、誰が実行したのか、パフォーマンスが変化していないか、コストをどう配分するのかを知る必要が出てきます。

Athena でシステムテーブルが使えるようになりました。第一弾として本日提供を開始する query_executions は、利用状況のデータを自動で記録し、オブザーバビリティ、利用状況の分析、監査といったユースケースに使えます。システムテーブルを有効にすると、すべてのワークグループで、クエリの完了から数分以内に利用状況のデータを参照できるようになります。Athena は利用状況のデータを、Amazon Simple Storage Service (Amazon S3) の機能である Amazon S3 Tables に Apache Iceberg テーブルとして保存します。保持期間は設定で変更できます。スキーマの定義、パーティショニング、コンパクション、スナップショットのメンテナンスを含むテーブルの管理は AWS が担うので、Athena から直接クエリするだけで済みます。テーブルを管理する運用の負担はかかりません。

Athena の利用状況のデータは、GetQueryExecution などの API、Amazon CloudWatch のメトリクス、AWS CloudTrail のログから取得できます。今回のリリースで、利用状況のデータを S3 テーブルとしても使えるようになりました。独自のパイプラインを構築・保守しなくても、直接検索、フィルタリング、集計、結合ができます。プラットフォームチームは、独自の抽出、変換、ロード (ETL) パイプラインを用意しなくても、ワークグループ別、ユーザー別、テーブル別にスキャンしたデータ量を示すコスト配分のダッシュボードを構築できます。さらに、AWS Agent Toolkit には、システムテーブルをクエリして利用パターンや最適化の提案を導き出すスキルが用意されています。Athena はデータをオープンな Apache Iceberg 形式で保存するため、DuckDB、Amazon Redshift などの Iceberg 互換エンジンからもクエリできます。

本記事では、システムテーブルとは何か、どう始めるのか、そして何より、システムテーブルで何ができるのかを紹介します。

課題: 規模が拡大した Athena ワークロードの把握

これまで、規模の大きなクエリワークロードを把握するには、クエリそのものを実行するよりも多くの手間がかかっていました。よくある次のような疑問を考えてみてください。

  • コストの配分: 今月、最もコストの高いクエリを実行したのはどのチームか?
  • パフォーマンス分析: 遅くなっているクエリや、普段より多くのデータをスキャンしているクエリはないか?
  • 監査とコンプライアンス: 前四半期に特定のテーブルに対してクエリを実行したのは誰か?
  • 運用状況の把握: 本番ワークロードのエラー率はどのくらいか?
  • 利用パターン: 日ごとのクエリ数はどのくらいで、ピークの時間帯はいつか?

以前は、どの疑問に答えるにも、Athena API、Amazon CloudWatch のメトリクス、AWS CloudTrail のログを自分でつなぎ合わせるか、クエリ履歴のスナップショットを取ってクエリできる形式で保存する独自のパイプラインを構築する必要がありました。つまり、分析パイプラインを分析するために、分析パイプラインを構築していたわけです。システムテーブルは、差別化につながらない重労働をなくします。

システムテーブルとは

最初のシステムテーブルである query_executions は、すべてのワークグループで完了した (成功したか、エラーで終了した) クエリ 1 件ごとに 1 行を記録します。記録する内容は次のとおりです。

  • クエリの識別情報: クエリ実行 ID、クエリ文字列、送信時刻。
  • コンテキスト: ワークグループ、カタログ、データベース、テーブル。
  • ユーザーアイデンティティ: クエリを送信したユーザー。
  • パフォーマンス: 合計実行時間、計画時間、キュー時間など。
  • リソースの消費量: スキャンしたバイト数、データ処理ユニット (DPU) 数。
  • 結果: 実行状態 (成功、失敗、キャンセル)、エラーの詳細情報。

クエリに関する情報がすべて 1 か所にそろうと、Athena ワークロードの捉え方が変わります。コンソールや API でクエリを 1 件ずつ調べるのではなく、クエリ履歴全体を対象に問いを立てられます。ほかの分析用データセットと同じように、集計、フィルタリング、傾向の分析、結合ができます。ダッシュボードを構築したり、定期的なレポートを設定したり、状況を把握したいときにアドホッククエリを実行したりできます。

始め方

システムテーブルは、数ステップで有効にできます。

  1. Athena コンソールを開きます。
  2. 左側のナビゲーションペインで、Administration の下にある System tables を選択します。
  3. Configure を選択し、Enable system tables for all your current and future resources をオンにします。
  4. (オプション) Data encryption を展開し、AWS Key Management Service (AWS KMS) のキーを選択します。キーを選択しない場合、Athena は Amazon S3 マネージドキー (SSE-S3) を使います。
  5. Save を選択します。Athena はアカウント内に、サービスが管理する Amazon S3 のテーブルバケットをプロビジョニングし、すべてのワークグループでクエリ実行の記録を始めます。

有効にすると、Athena は新しいクエリの実行を自動で記録します。システムテーブルには、ほかの Athena テーブルと同じように、コンソールのクエリエディタ、API や SDK、JDBC ドライバーや ODBC ドライバーからアクセスできます。

AI エージェントでシステムテーブルからインサイトを得る

自然言語で質問して、システムテーブルを探索することもできます。システムテーブルは AWS Glue Data Catalog の標準的なテーブルなので、Kiro や Claude Code など、Model Context Protocol (MCP) に対応した AI エージェントから参照できます。接続先は AWS MCP Server です。AWS MCP Server はマネージド型の MCP サーバーで、既存の AWS Identity and Access Management (IAM) の認証情報を使って、エージェントから AWS にアクセスできます。

安定した結果を得るには、AWS が AWS Agent Toolkit で公開している、Athena システムテーブル向けのオープンソースの Agent Skill を使ってください。スキルは、エージェントが機能をうまく使えるように教える指示と検証済みの例をまとめたパッケージで、バージョン管理されています。Athena システムテーブル向けのスキルには、システムテーブルのスキーマとクエリ例のライブラリが含まれています。パーティション列で絞り込む、テーブルを読み取り専用として扱うといった、クエリを正しく、コスト効率よく保つための決まりごとも組み込まれています。スキルを読み込んだエージェントは、正しい列名で、パーティションプルーニングによってスキャン量を抑えた SQL を書きます。自由形式のプロンプトのように、結果が予測しにくくなることはありません。スキルはオープンソースで、今後追加される新しいシステムテーブルにも対応するよう設計されています。

エージェントは質問を SQL に変換して Athena で実行し、答えを返します。会話を続けて結果を絞り込んだり、傾向をグラフにしたりもできます。

  • コストの配分: 「先月スキャンしたデータ量が最も多かったワークグループはどれですか?先々月と比べてどうですか?」
  • 監査とコンプライアンス: 「前四半期に customer_orders テーブルにアクセスしたクエリをすべて、実行したユーザーとあわせて一覧にしてください。」
  • 運用状況の把握: 「ユーザーの構文エラーを除くと、今週の本番ワークグループのエラー率はどのくらいですか?」

エージェントが使う IAM の認証情報は、最小権限に絞ってください。Athena、AWS Glue、システムテーブルへの読み取り専用のアクセス権があれば十分です。質問するだけなら書き込み権限は必要ありません。AWS MCP Server は IAM ベースのアクセス制御を使い、すべての API 呼び出しを CloudTrail に記録するので、エージェントがユーザーに代わって実行した操作の監査証跡がすべて残ります。

システムテーブルでできること

以降のセクションでは、特によくあるユースケースを、それぞれの代表的なクエリとあわせて紹介します。ここで紹介するクエリは出発点です。すぐに実行できるクエリをさらに多く知りたい場合は、Athena システムテーブル向けの Agent Skill のクエリ例を参照するか、スキルを使ってエージェントにクエリを書かせてください。

利用パターン: Athena の使われ方を把握する

システムテーブルを使うと、組織全体で Athena がどう使われているかの全体像をつかめます。利用パターンは多くのチームが最初に調べる項目で、ワークロードを理解するうえでの基準になります。

日ごとのクエリ数

クエリ数の推移を追跡します (‘day’ を ‘hour’ に置き換えると、ピークの時間帯がわかります)。

SELECT
    DATE_TRUNC('day', submission_date_time) AS day,
    COUNT(*) AS query_count
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '30' DAY
GROUP BY 1
ORDER BY 1
SELECT
    DATE_TRUNC('week', submission_date_time) AS week,
    work_group_name,
    COUNT(*) AS query_count,
    COUNT(DISTINCT principal_arn) AS distinct_users
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '90' DAY
GROUP BY 1, 2
ORDER BY 1, 2

クエリサイズの分布

SELECT
    CASE
        WHEN data_scanned_size = 0 THEN '0 bytes'
        WHEN data_scanned_size < 1048576 THEN '<1 MB'
        WHEN data_scanned_size < 10485760 THEN '1-10 MB'
        WHEN data_scanned_size < 104857600 THEN '10-100 MB'
        WHEN data_scanned_size < 1073741824 THEN '100 MB-1 GB'
        WHEN data_scanned_size < 10737418240 THEN '1-10 GB'
        WHEN data_scanned_size < 107374182400 THEN '10-100 GB'
        ELSE '>100 GB'
    END AS scan_bucket,
    COUNT(*) AS query_count,
    ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) AS percent_of_query_count
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '30' DAY
AND state_enum = 'SUCCEEDED'
GROUP BY 1
ORDER BY MIN(data_scanned_size)

コストの配分: チームやユーザーごとに費用を割り当てる

スキャンしたデータ量に応じて課金される Athena の料金モデルでは、スキャンしたバイト数をユーザーやワークグループに割り当てれば、そのままコストの配分になります。システムテーブルを使えば、独自の計測パイプラインを立ち上げなくても、チャージバックやショーバックのレポートを作成できます。コストを見積もるには、リージョンごとの 1 TB あたりの料金を確認するか、AWS Price List API で最新の料金をプログラムからダウンロードしてください。

請求期間中にユーザーがスキャンしたデータ量の合計

SELECT
    work_group_name,
    region_name,
    ROUND(SUM(data_scanned_size) / POWER(1024.0, 4), 3) AS total_tb_scanned,
    COUNT(*) AS query_count,
    ROUND(SUM(data_scanned_size) * 100.0 / SUM(SUM(data_scanned_size)) OVER (), 3) AS percent_of_total_tb_scanned
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '30' DAY
AND state_enum = 'SUCCEEDED'
GROUP BY 1, 2
ORDER BY 1, 2

work_group_name を principal_arn に変えると、同じレポートをユーザー別に分けられます。

パフォーマンス分析: パフォーマンスの問題を見つけて解決する

パフォーマンスの傾向を把握すれば、劣化を早期に捉え、最も重要なクエリを最適化できます。

過去 7 日間で最も遅いクエリを見つける

SELECT
    query_execution_id,
    work_group_name,
    principal_arn,
    submission_date_time,
    total_execution_duration / 1000.0 AS execution_seconds,
    data_scanned_size / POWER(1024, 3) AS data_scanned_gb,
    SUBSTR(query_string, 1, 200) AS query_preview
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '7' DAY
AND state_enum = 'SUCCEEDED'
ORDER BY total_execution_duration DESC
LIMIT 50

ワークロードのパフォーマンス問題を時系列で検出する

ワークグループ内の実行時間の集計値を今週と先週で比べ、ユーザーが気づく問題になる前に傾向をつかみます。

WITH weekly_stats AS (
    SELECT
        work_group_name,
        IF(submission_date_time >= DATE_TRUNC('week', CURRENT_DATE), 'this_week', 'last_week') AS period,
        COUNT(*) AS query_count,
        AVG(total_execution_duration) AS avg_exec_ms,
        APPROX_PERCENTILE(total_execution_duration, 0.95) AS p95_exec_ms,
        SUM(data_scanned_size) AS total_bytes_scanned
    FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
    WHERE submission_date_time >= DATE_TRUNC('week', CURRENT_DATE) - INTERVAL '7' DAY
    AND state_enum = 'SUCCEEDED'
    GROUP BY 1, 2
)
SELECT
    tw.work_group_name,
    lw.query_count AS last_week_queries,
    tw.query_count AS this_week_queries,
    lw.avg_exec_ms / 1000.0 AS last_week_avg_sec,
    tw.avg_exec_ms / 1000.0 AS this_week_avg_sec,
    ROUND((tw.avg_exec_ms - lw.avg_exec_ms) * 100.0 / lw.avg_exec_ms, 1) AS avg_pct_change,
    lw.p95_exec_ms / 1000.0 AS last_week_p95_sec,
    tw.p95_exec_ms / 1000.0 AS this_week_p95_sec
FROM weekly_stats tw
JOIN weekly_stats lw ON tw.work_group_name = lw.work_group_name
WHERE tw.period = 'this_week'
AND lw.period = 'last_week'
ORDER BY avg_pct_change DESC

キュー時間を分析してキャパシティの逼迫度を把握する

SELECT
    work_group_name,
    DATE(submission_date_time) AS query_date,
    COUNT(*) AS query_count,
    AVG(query_queue_time_duration) / 1000.0 AS avg_queue_sec,
    APPROX_PERCENTILE(query_queue_time_duration, 0.50) / 1000.0 AS median_queue_sec,
    APPROX_PERCENTILE(query_queue_time_duration, 0.95) / 1000.0 AS p95_queue_sec,
    MAX(query_queue_time_duration) / 1000.0 AS max_queue_sec
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '14' DAY
GROUP BY work_group_name, DATE(submission_date_time)
HAVING AVG(query_queue_time_duration) > 1000
ORDER BY avg_queue_sec DESC

スキャンしたデータ量の多いクエリを見つける

スキャンするデータ量が最も多いクエリを特定します。スキャン量の多いクエリはコストを押し上げる最大の要因で、最適化 (パーティショニング、述語のプッシュダウン、データ形式の変更) の最有力候補です。

SELECT
    query_execution_id,
    work_group_name,
    principal_arn,
    submission_date_time,
    data_scanned_size / POWER(1024, 4) AS data_scanned_tb,
    total_execution_duration / 1000.0 AS execution_seconds,
    SUBSTR(query_string, 1, 300) AS query_preview
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '7' DAY
AND state_enum = 'SUCCEEDED'
ORDER BY data_scanned_size DESC
LIMIT 50

ここで紹介したクエリを使えば、プラットフォームチームは Athena をひとつのサービスとして運用できます。サービスレベル目標 (SLO) を定め、傾向を可視化し、何かが変わったときには早めに気づけます。

監査とコンプライアンス: 誰が、いつ、何を実行したかを把握する

規制やセキュリティの要件がある組織では、システムテーブルを、構造化されたクエリ可能な監査証跡として使えます。

特定のユーザーが一定期間に実行したすべてのクエリ

SELECT
    query_execution_id,
    work_group_name,
    submission_date_time,
    state_enum,
    total_execution_duration / 1000.0 AS execution_seconds,
    data_scanned_size / POWER(1024, 2) AS data_scanned_mb,
    SUBSTR(query_string, 1, 200) AS query_preview
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE principal_arn = 'arn:aws:iam::111122223333:user/example-user' -- Replace with target user
AND submission_date_time >= CURRENT_DATE - INTERVAL '7' DAY
ORDER BY submission_date_time DESC

特定のテーブルにアクセスしたクエリ

SELECT
    query_execution_id,
    work_group_name,
    principal_arn,
    submission_date_time,
    state_enum,
    ROUND(data_scanned_size / POWER(1024.0, 3), 3) AS data_scanned_gb,
    SUBSTR(query_string, 1, 200) AS query_preview
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
CROSS JOIN UNNEST(tables_accessed) AS t(tbl)
WHERE tbl.database_name = 'my_database' -- Replace with target database
AND tbl.table_name = 'my_table' -- Replace with target table
AND submission_date_time >= CURRENT_DATE - INTERVAL '30' DAY
ORDER BY submission_date_time DESC

Athena はシステムテーブルを Iceberg のデータとしてお客様自身のアカウントに保存し、レコードを書き込めるのは Athena サービスだけです。そのため、システムテーブルは監査に使える信頼性の高いクエリアクティビティの記録になります。保持期間、アクセスポリシー、暗号化はお客様が管理します。

運用監視: エラー率とワークロードの健全性を追跡する

システムテーブルを使うと、CloudWatch の集計メトリクスでわかる範囲を超えて、Athena ワークロードの運用状況を可視化できます。データはクエリ単位なので、ユーザーの構文エラーが急増しただけの問題のないケースと、対処が必要なシステムエラーの急増とを区別できます。集計メトリクスでは両者を見分けられません。

ワークグループ別のエラー率

WITH error_stats AS (
    SELECT
        work_group_name,
        COUNT(*) AS total_queries,
        COUNT(*) FILTER (WHERE state_enum = 'FAILED' AND error_category_enum = 1) AS system_errors,
        COUNT(*) FILTER (WHERE state_enum = 'FAILED' AND error_category_enum = 2) AS user_errors
    FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
    WHERE submission_date_time >= CURRENT_DATE - INTERVAL '7' DAY
    GROUP BY work_group_name
)
SELECT
    work_group_name,
    total_queries,
    system_errors,
    ROUND(system_errors * 100.0 / SUM(system_errors) OVER (), 1) AS percent_of_all_system_errors,
    user_errors,
    ROUND(user_errors * 100.0 / SUM(user_errors) OVER (), 1) AS percent_of_all_user_errors
FROM error_stats

急増の原因を調べるには、失敗したクエリを error_category_enum と error_message でグループ化し、どのエラーがどこに集中しているかを正確に確認します。

リソースを使い果たしたクエリを特定する

リソースを使い果たしたクエリは最適化の有力候補です。パーティショニングの改善、クエリの書き換え、キャパシティの追加が効く可能性があります。

SELECT
    query_execution_id,
    work_group_name,
    principal_arn,
    submission_date_time,
    error_message,
    ROUND(data_scanned_size / POWER(1024.0, 3)) AS data_scanned_gb,
    ROUND(total_execution_duration / 1000.0, 1) AS execution_seconds,
    SUBSTR(query_string, 1, 200) AS query_preview
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '7' DAY
AND state_enum = 'FAILED'
AND error_message LIKE 'Query exhausted resources%'
ORDER BY data_scanned_size DESC

キャパシティ予約の最適化

キャパシティ予約を使っている場合は、プロビジョニングしたキャパシティの使われ方をシステムテーブルで確認できます。Athena が dpu_count 列に値を入れるのは、キャパシティ予約で実行したクエリだけです。そのため、dpu_count 列には 2 つの役割があり、予約済みのキャパシティで実行したクエリがどれかと、各クエリが消費した DPU 数の両方がわかります。予約が消費した DPU 時間の推移を追えば、予約のサイズが適切かどうかを確認できます。また、前述の実行時間とキュー時間のパターンから、オンデマンドのワークロードがキャパシティ予約に適しているかどうかも判断できます。

キャパシティ予約で実行したクエリが消費した週ごとの DPU 時間

SELECT
    DATE_TRUNC('week', submission_date_time) AS week,
    COUNT(*) AS reservation_queries,
    ROUND(SUM(dpu_count * total_execution_duration / 3600000.0), 1) AS dpu_hours
FROM "s3tablescatalog/aws-athena"."metadata"."query_executions"
WHERE submission_date_time >= CURRENT_DATE - INTERVAL '90' DAY
AND state_enum = 'SUCCEEDED'
AND dpu_count > 0 -- populated only for capacity-reservation queries
GROUP BY 1
ORDER BY 1

アーキテクチャとデータモデル

Athena のシステムテーブルは、特別な種類の S3 テーブルバケットを使います。通常の S3 テーブルバケットと同じように動作しますが、書き込めるのは AWS のサービスだけです。そのため、データを所有するメリットを得ながら、レコードの完全性も保てます。

  • お客様がデータを所有 – データはお客様のアカウント内にあり、お客様のキーで暗号化され、お客様のポリシーで管理されます。
  • 不変のレコード – システムテーブルに書き込めるのは Athena だけです。お客様のアカウント内のどの IAM プリンシパルも、個々のレコードを変更・削除できません。
  • 標準的な形式 – Athena、Amazon Redshift、Amazon EMR、Apache Spark、Trino など、Iceberg 互換のエンジンであればどれでもデータを読み取れます。
  • 自動メンテナンス – コンパクション、スナップショットの管理、設定した保持期間に基づくデータの有効期限切れの処理は S3 Tables が行います。

Athena は保持期間の既定値を設定しません。S3 Tables でレコードの有効期限を設定するまで、レコードは保持されます。期限は最短 1 日で、上限はありません。データは効率よくスキャンできるようにパーティション分割され、クエリの実行データはバッチで届きます。通常はクエリの完了から数分以内です。パーティション列を確認するには、DESCRIBE ステートメントを使います。

まとめ

Amazon Athena のシステムテーブルを使えば、独自のインフラストラクチャを用意しなくても、クエリワークロードの状況をクエリで可視化できます。チームへのコスト配分、パフォーマンス劣化の調査、コンプライアンスの証跡作成、Athena の使われ方の把握と、目的が何であっても、クエリ 1 本で答えが得られるようになりました。Athena はシステムテーブルを AWS Glue Data Catalog に登録し、オープンな Apache Iceberg 形式でお客様自身のアカウントに保存するため、Amazon Quick Sight やビジネスインテリジェンス (BI) ツールから直接参照できます。これまでチームが保守してきた独自のパイプラインは不要になります。

まずは Athena コンソールからシステムテーブルを有効にしてください。詳しくは、Amazon Athena ユーザーガイドの「System Tables」を参照してください。

著者について

Pathik Shah

Pathik Shah

Pathik は、Amazon Web Services のシニアアナリティクスアーキテクトです。2015 年に AWS に入社して以来、ビッグデータ分析を専門とし、お客様が AWS の分析サービスを使ってスケーラブルで堅牢なソリューションを構築できるよう支援しています。

Theo Tolv

Theo Tolv

Theo は、スウェーデンのストックホルムを拠点とするプリンシパルアナリティクスアーキテクトです。キャリアの大半を通じて規模の大小を問わずデータに携わり、2008 年から AWS 上で動くアプリケーションを構築してきました。余暇には電子工作をしたり、スペースオペラを読んだりして過ごしています。

Raza Hafeez

Raza Hafeez

Raza は、Amazon Redshift のシニアテクニカルプロダクトマネージャーです。エンタープライズデータウェアハウスの構築と最適化に 15 年以上携わってきました。あらゆる規模のお客様にとって、クラウドでの分析を手軽で費用対効果の高いものにすることに情熱を注いでいます。


この記事は Kiro が翻訳を担当し、Solutions Architect の Woosuk Choi がレビューしました。