Athena × QuickSightで「運用できる」コンタクトセンター可視化を作る(全2回連載 第2回)
これは Amazon Connect 分析データレイク(Analytics Data Lake)をテーマにした全2回連載の第2回です。
第1回はこちら:
対象読者と、今回やること
対象読者はだいたいこのあたりです。
- Analytics Data Lake を有効化して、Athena からクエリできる状態にはなった
- QuickSight で「とりあえず」グラフを作れた(第1回のハンズオンまで到達)
- ただ、運用し始めるとすぐにこうなる
- KPIの定義が人によって違う
- QuickSightの計算フィールドが増殖して「どれが真実?」になりがち
- データ更新や権限が泥臭くなる
- Athenaコストが読めなくなる
この回でやることは3つです。
- Athena View を Semantic Layer として扱う前提で、KPI定義と粒度を揃える
- **QuickSight のデータセット設計(SPICE / Direct Query / Refresh)**を、運用視点で整理する
- 「コンタクトセンターのダッシュボード」を 役割別に設計して、使われる形に落とす
0. 前提:Analytics Data Lakeは“ほぼリアルタイム”ではない
まず大事な前提。Analytics Data Lake は便利ですが、「秒単位で追えるリアルタイム基盤」ではありません。
- レコードが作られてから 反映まで多少の遅延があり、概ね1時間以内に利用可能、という位置づけです[1]。
つまり、
- 運用KPIの「当日」「直近1時間」レベルなら十分
- 「今この瞬間の混雑」を秒で追いたい用途は、別途(メトリクスAPIやリアルタイムパイプライン)が必要
という整理になります。
1. “運用できる可視化”の基本設計:Raw / Semantic / BI を分ける
第1回でも触れましたが、ここが今回の主役です。
- Raw(Analytics Data Lakeのテーブル):事実の一次ソース。触るのは最小限
- Semantic(Athena View / CTAS):KPI定義・粒度・ディメンションをここに集約
- BI(QuickSight):表示とフィルタに寄せ、ロジックは薄く
「ロジックをどこに置くか」を一度決めると、あとが楽になります。
1.1 1枚で見る(図)
1.2 命名規約(例)
運用では「一覧したときに意味が分かる」が地味に効きます。
- Raw(触らない想定でも、区別のために prefix を付けると吉)
raw_*
- Semantic(View)
vw_*
- マート(必要なら。CTASで作る/日次集計を置く)
mart_*
例:
vw_contact_dailyvw_queue_kpi_15minvw_agent_occupancy_15min-
mart_queue_kpi_daily(重い集計を日次で固めるなど)
2. Athena 側:Viewで「粒度」と「定義」を固定する
ここからが実務のキモです。
2.1 粒度は、まず “15分” から始めるのが無難
コンタクトセンターでよくある粒度はこのあたり:
- リアル運用:5分 / 15分
- 日次レポート:日次
- 経営向け:週次 / 月次
いきなり全部作ると散ります。まずは 15分粒度 + 日次 の2本立てにするのが扱いやすいです。
- 15分:SVのモニタリング(SL/ASA/入電/放棄/稼働)
- 日次:現場改善・経営レポート(AHT/CS/品質/要因分析)
2.2 タイムゾーンは最初に潰す
Connect系は ISO8601 文字列の timestamp が混ざりがちです。View 側で timestamp型に寄せ、必要ならJSTに寄せるのが安全です。
-- 例:ISO8601文字列 -> timestamp
from_iso8601_timestamp(initiationtimestamp) as initiation_ts_utc
JST に寄せる場合は AT TIME ZONE を使う(環境の要件に合わせて統一)。
2.3 「問い合わせ(Contact)」と「エージェント(Agent)」は別ファクトとして扱う
よくある事故パターン:
- Contact単位のテーブルと Agent interval 系を安易にJOINして、多対多で爆発する
- QuickSight でJOINして、意図しない重複が入り KPI が壊れる
まずは割り切って、
- Contactファクト:1件の問い合わせの結果
- Agent intervalファクト:15分単位の稼働
を分け、両方が必要なダッシュボードは “並べて見る” から始めるのが安全です。
3. QuickSight 側:データセット設計(SPICE / Direct Query / Refresh)
第1回では「まず動かす」ためにデータセットを作りました。ここでは 運用のために 設計します。
3.1 SPICE と Direct Query、どう使い分けるか
ざっくり方針はこれ。
- SPICE(基本):よく見るダッシュボード、インタラクティブ操作が多い、複数ビジュアルがある
- Direct Query(例外):直近データが重要、データ量が巨大でSPICEに載せない、もしくは「とりあえず」確認用
Analytics Data Lakeは「だいたい1時間以内に入る」ので、実務ではこう分かれやすいです。
- SVの「今朝からの状況」:Direct Query でもOK(ただしコスト注意)
- 経営向けの週次・月次:SPICE で良い(むしろSPICEで固めたい)
- 品質・要因分析:SPICE + 必要なら日次/週次マート化
補足:SPICE/Direct Query の判断要素は AWS の公式ブログにまとまっています。本文末に参考リンクを載せます。
3.2 Refresh戦略:SPICEは "フル更新" から卒業する
SPICE を使うなら「更新設計」がセットです。
- SQLベースのSPICEデータセットは 増分更新(Incremental Refresh) を設定できます。
- ポイントは「増分キー(日付列)」と「ルックバック期間」をちゃんと決めること。
増分更新の前提条件
増分更新を使うには、以下の条件を満たす必要があります:
- データセットが SPICE モードであること(Direct Query では不可)
-
増分判定に使える列があること
- 例:
interval_15min(timestamp)、dt(日付)、ingested_at(取り込み時刻)など
- 例:
- できれば Athena 側でパーティション化されていること(増分クエリが軽くなる)
増分更新は「指定した期間(ルックバック)だけ取り込み直して、それ以外は前回の SPICE を使う」動きになります。遅延到着データがある場合、ルックバックを長めにしないと取りこぼします。
設定方法(Enterprise Edition)
QuickSightのEnterprise Editionでは、データセット編集画面から増分更新を設定できます:
-
データセット詳細画面で 「データセットを編集」 をクリック
-
画面上部の 歯車アイコン ⚙️ → 「増分更新を設定」 を選択
-
以下を設定:
-
増分列:
interval_15min(タイムスタンプ列) -
ルックバックウィンドウ:
7日
-
増分列:
-
「更新」タブで更新スケジュールを設定:
- 頻度: 1時間ごと
- タイムゾーン: Asia/Tokyo

運用上のおすすめ(例):
- ルックバック:2〜7日(遅延・再送・訂正を吸収したい場合は長め)
- 実行頻度:1日数回〜1時間おき("ほぼ1時間以内"の特性に合わせる)
※ここは実データの遅延・訂正の出方に依存するので、後述の「計測メモ」で一度測るのがおすすめです。
4. 実装の型:まずは “Semantic View → Dataset → Dashboard” を一本道にする
「QuickSightの計算フィールドを育てる」より、先に Athena View を育てるほうが長期的に安定します。
4.1 例:Queue KPI(15分粒度)を View で作る
以下は、実際の Analytics Data Lake の CTR(Contact Trace Record)テーブルを元にした実装例です。
前提:
- 元テーブル:
connect_raw.ctr_v2(パーティションプロジェクション対応) - View作成先:
connect_curated.vw_queue_kpi_15min - Analytics Data Lake は「だいたい1時間以内に入る」ため、リアルタイムではなく運用分析向け
CREATE OR REPLACE VIEW connect_curated.vw_queue_kpi_15min AS
SELECT
-- 15分バケット (timestamp型にキャスト)
CAST(
date_trunc('minute', from_iso8601_timestamp(initiationtimestamp))
- (minute(from_iso8601_timestamp(initiationtimestamp)) % 15) * interval '1' minute
AS timestamp
) as interval_15min,
-- Queue情報
queue.arn as queue_arn,
queue.name as queue_name,
-- 対応済みコンタクト数(エージェントが対応したもの)
count_if(agent.username IS NOT NULL AND disconnectreason IS NOT NULL) as handled,
-- 放棄コンタクト数(エージェント接続前に顧客が切断)
count_if(agent.username IS NULL AND channel = 'VOICE') as abandoned,
-- 平均待機時間(秒)- initiationからconnectedtosystemまで
avg(
CASE
WHEN connectedtosystemtimestamp IS NOT NULL
THEN date_diff('second',
from_iso8601_timestamp(initiationtimestamp),
from_iso8601_timestamp(connectedtosystemtimestamp))
ELSE NULL
END
) as asa_seconds,
-- 平均対応時間(秒)- connectedからdisconnectまで
avg(
CASE
WHEN connectedtosystemtimestamp IS NOT NULL AND disconnecttimestamp IS NOT NULL
THEN date_diff('second',
from_iso8601_timestamp(connectedtosystemtimestamp),
from_iso8601_timestamp(disconnecttimestamp))
ELSE NULL
END
) as aht_seconds,
-- 総コンタクト数
count(*) as total_contacts
FROM connect_raw.ctr
WHERE
-- 過去90日のデータに絞る
from_iso8601_timestamp(initiationtimestamp) >= current_timestamp - interval '90' day
-- queueが存在するもののみ
AND queue.name IS NOT NULL
GROUP BY
1, 2, 3
ORDER BY
interval_15min DESC, queue_name;
- 重要なのは KPI定義をここに集約すること
- QuickSight 側は
avg(aht_seconds)などの単純集計で済むようにする
4.2 QuickSight データセット定義:View をそのままソースにする
QuickSight でデータセットを作成する際は、Athena View を直接ソースとして指定します。
基本設定
- データソース: Athena(事前に作成済みのデータソース接続)
-
データベース:
connect_curated -
テーブル:
vw_queue_kpi_15min(View) - インポートモード: SPICE(推奨)
View をソースにする利点:
- ✅ KPI定義が一元管理される:View側でKPI計算が完了しているため、QuickSightでは単純な集計のみ
- ✅ カラムがシンプル:8カラム程度なので、データセット設計がシンプル
- ✅ パフォーマンス:集計済みデータなので、SPICEへの取り込みが高速(実測 421KB 程度)
データセット構成例
| カラム名 | データ型 | 用途 |
|---|---|---|
interval_15min |
DATETIME | 時系列分析・増分更新キー |
queue_arn |
STRING | キュー識別子 |
queue_name |
STRING | キュー名(フィルタ・グルーピング) |
handled |
INTEGER | 対応済みコンタクト数 |
abandoned |
INTEGER | 放棄コンタクト数 |
asa_seconds |
DECIMAL | 平均待機時間(秒) |
aht_seconds |
DECIMAL | 平均対応時間(秒) |
total_contacts |
INTEGER | 総コンタクト数 |
Calculated Field の追加(オプション)
QuickSight のデータセット定義で、ビジネス指標を追加する場合:
// 放棄率 (%)
ifelse({total_contacts} > 0, ({abandoned} / {total_contacts}) * 100, 0)
// ASA(分)
{asa_seconds} / 60
// AHT(分)
{aht_seconds} / 60
設計原則:View側で計算できるものはViewに寄せ、QuickSight側はユーザーが理解しやすい表示単位への変換程度に留める。




5. “役割別ダッシュボード”の型(よくある4枚)
5.1 経営向け(週次 / 月次)
目的:傾向と意思決定
よく置くもの:
- 入電/処理件数(チャネル別)
- SL/ASA/AHT(週次の推移)
- 品質(評価スコア、センチメントの悪化割合)
- 重要カテゴリ(問い合わせ理由トップN)
設計ポイント:
- SPICE前提(サクサク動くことが価値)
- “上から読んで”理解できる(KPI→要因→内訳)
5.2 SV向け(当日〜直近)
目的:現場運用
よく置くもの:
- 今日の入電・放棄・SL(時間帯)
- キュー別の詰まり(Top N)
- エージェント稼働(占有率/ACW/離席)
設計ポイント:
- 15分粒度が中心
- Direct Query にしたい誘惑が出るが、Athenaコストとトレードオフ
- “重いビジュアル”は下に置く(QuickSight は上から順に評価されるので体感が変わる)
5.3 品質・改善向け(QA/企画)
目的:原因分析と施策
よく置くもの:
- Contact Lens のキーワード/カテゴリ
- センチメント分布(悪化の多いキュー/時間帯)
- 再入電(リピート)や転送の多いパターン
設計ポイント:
- ここは Join が増えやすいので、Athena View で “分析用フラットテーブル” を作ると安定
- 期間を絞るUI(パラメータやフィルタ)を先に用意する
5.4 エージェント本人向け(セルフモニタ)
目的:自己改善(ただし見せ方は繊細)
よく置くもの:
- 自分の対応件数・AHT・ACW
- 直近の評価/フィードバック
- チーム平均との差(出し方は運用と相談)
設計ポイント:
- RLS をちゃんと設計(自分のデータだけ)
- “ランキング”を前面に出しすぎない(現場の空気が荒れる)
6. Athena コストとパフォーマンス:最低限これだけ
QuickSight を Direct Query で使い始めると、Athena コストは簡単に跳ねます。
6.1 Workgroup でガードレールを作る
Athena の Workgroup は、
- クエリ結果の保存先
- 1クエリあたりのスキャン上限
- メトリクス
などを強制できます。


おすすめの運用:
- QuickSight 用 Workgroup を分ける(例:
wg_quicksight_connect) - 1クエリのスキャン上限を設定して事故を防ぐ
- 出力先は専用S3に固定
7. まとめ:第2回の結論
- 「運用できる可視化」は、KPI定義の置き場所でだいたい決まる
- Rawは触らない
- Semantic(Athena View)で定義を集約
- QuickSightは表示に寄せる
- QuickSight は SPICE/Direct Query/Refresh を設計しないと、コストと運用が破綻する
- ダッシュボードは 役割別に分けると使われる(全部盛りはだいたい死ぬ)
参考リンク(公式中心)
- Amazon Connect analytics data lake(管理者ガイド)
- Simplify custom contact center insights with Amazon Connect analytics data lake(AWS公式ブログ)
- Best practices for Amazon QuickSight SPICE and direct query mode(AWS公式ブログ)
- Refreshing SPICE data / Incremental refresh(QuickSightユーザーガイド)
- Athena workgroup data usage controls(Athenaユーザーガイド)
- Tips and tricks for high-performant dashboards in Amazon QuickSight(AWS公式ブログ)
-
Amazon Connect analytics data lake は、レコード作成後の処理遅延を経て「1時間以内」に利用可能になる旨が記載されています。 https://docs.aws.amazon.com/connect/latest/adminguide/data-lake.html ↩︎
Discussion