🐈

Lookerの備忘録④ 集計認識(Aggregate Awareness)とは前もってユーザーが欲しそうな結果を用意しておくということ

2024/12/10に公開

前回の続きです

大量のデータに対して効率良く集計を行い、高速なレスポンスを得ることは、BIツールを運用する上で避けては通れない課題です。
Lookerにはこれまで、PDT(Persistent Derived Table)を用いて事前集計や差分更新などを行う手法がありました。
一方で、Looker特有の仕組みとして、集計認識(Aggregate Awareness)という機能があります。

本記事では、以下の内容を整理します。

例の如くこの公式ドキュメントを参照

  • 集計認識の基本的な概念
  • 集計認識を有効活用するためのLookML実装例
  • PDTとの違いとそれぞれのメリット・デメリット
  • 環境や要件に応じた使い分けガイド

集計認識(Aggregate Awareness)とは?

集計認識(Aggregate Awareness)は、Lookerがクエリ実行時に自動的に最適な「集計済みテーブル」を選択する仕組みです。
同じ指標に対して複数の粒度(graularity)や、事前集計済みテーブル(マテリアライズドビューやPDTを含む)を用意しておくと、Lookerはユーザーが発行するクエリの集計粒度に応じて、最も効率的なソースを自動的に選びます。

集計認識の狙い

  • パフォーマンス向上
    同じ指標を日次・月次・年次など、異なる粒度で事前集計しておくことで、細粒度な生データテーブルを毎回スキャンする必要がなくなります。
    Lookerはクエリの詳細を理解し、適した集計テーブルを選ぶため、無駄な計算を省きレスポンスを高速化できます。

  • メンテナンス性向上
    複数の集計レベルを用意しておいても、Lookerが自動で選択するため、ユーザーは意識することなく最適なテーブルを利用できます。
    開発者はLookML上で定義するだけで、エンドユーザーは常にベストなパフォーマンスを享受可能です。

集計認識の実装例

集計認識を実現するためには、LookMLでaggregate_tableパラメータを使い、特定の粒度・フィールドで集計済みテーブルを定義します。
そして、exploreview内でそのaggregate_tableを参照することで、Lookerはクエリ最適化を行います。

基本的なLookML例

以下は、ordersテーブルをもとに、日次粒度で集計した売上集計テーブルをaggregate_tableとして定義し、Lookerに集計認識させる例です。

explore: orders { ## ordersというテーブルを使って今から集計データ作るよーということ
  aggregate_table: daily_orders_agg {
    query: {
      dimensions: [orders.created_date]
      measures: [orders.total_revenue, orders.order_count] ##ここでは事前設定したtypeが影響受ける。sumであればdimensionsでgroupbyされるので、それによるsum結果を返す
      timeframe: day
    }

    materialization: { ## ここでは集計した結果をマテリアライズドするよーつまりPDTにするよということ。そのときに以下に増分として追加することを明示する
      increment_key: created_date
      sql_trigger_value: SELECT MAX(created_date) FROM WH.schema.orders
    }

    # Snowflakeなどでこの集計テーブルを作るためのSQLをLookerが生成し、PDTのように管理します。
  }
}

このような定義を行うと、Lookerはユーザーが日次レベルで売上合計やオーダー数を求めるクエリを発行した際に、このdaily_orders_aggを自動選択し、生データへのアクセスをスキップできます。

複数粒度の集計テーブルを用意する場合
集計認識は1種類に限りません。たとえば、日次、週次、月次の3種類の集計テーブルをaggregate_tableとして定義しておけば、クエリ粒度に合わせてLookerが最適なテーブルを選びます。

explore: orders {
  aggregate_table: daily_orders_agg { ... }
  aggregate_table: monthly_orders_agg { ... }
}

より集計認識を深掘りします

集計認識(Aggregate Awareness)は、Lookerがユーザーが実行するクエリ内容を理解し、最適な事前集計済みテーブルを自動的に選ぶ仕組みです。
初心者向けに、もう少し丁寧な解説と具体例を紹介します。

なぜ集計認識が重要なのか?

想像してみてください、ビジネス上で日々発生する大量の注文データordersテーブルがあります。このテーブルは、何百万行、何千万行と増え続ける可能性があります。
ユーザーが「先月の日ごとの売上合計」を見たいと思った場合、もし生のordersテーブルに直接クエリを投げれば、全件スキャンが必要になるかもしれません。これではレスポンスが遅く、ユーザー体験はイマイチです。

そこで、あらかじめordersテーブルから「日次レベルの売上合計をまとめたテーブル」を作っておけば、そこから取得するだけで素早く結果を返せます。
しかし問題は、こうした「日次集計テーブル」や「月次集計テーブル」など、異なる粒度のテーブルをたくさん用意した場合に、ユーザーや開発者がどのテーブルを使うか常に意識しなければならないことです。

集計認識は、こうした悩みを解決します。
Lookerに「日次用」「月次用」「年次用」など複数の集計済みテーブルを定義しておけば、ユーザーがクエリで「日ごとの集計結果」を求めた時は日次用テーブルを、「月ごとの集計結果」を求めた時は月次用テーブルをLookerが自動的に選んでくれるのです。(これは非常にありがたいです。いろんな人から日次のデータの月次集計だとユニークのカウントになってないから困る、とかそんなお声をいただきます)

具体的なLookML例

シナリオ

  • 生データテーブル:orders(個々の注文が1行)
  • 必要な集計粒度:
    • 日次レベル(日ごとの売上合計)
    • 月次レベル(月ごとの売上合計)

定義例

explore: orders {
  # 日次集計テーブル定義
  aggregate_table: daily_orders_agg {
    query: {
      dimensions: [orders.created_date]
      measures: [orders.total_revenue, orders.order_count]
      timeframe: day
    }
    materialization: {
      increment_key: created_date ## 毎日差分だけ更新します
      sql_trigger_value: SELECT MAX(created_date) FROM WH.schema.orders ## きっかけは元データのcreated_dateに変更があった場合
    }
  }

  # 月次集計テーブル定義
  aggregate_table: monthly_orders_agg {
    query: {
      dimensions: [orders.created_month]
      measures: [orders.total_revenue, orders.order_count]
      timeframe: month
    }
    materialization: {
      increment_key: created_month
      sql_trigger_value: SELECT MAX(created_date) FROM WH.schema.orders
    }
  }
}

  # 月次集計利用ユーザー数テーブル定義
  aggregate_table: monthly_uniqueuser_agg {
    query: {
      dimensions: [orders.created_month]
      measures: [orders.total_revenue, orders.unique_user_count] ## ここでunique_user_countは元のderived_tableではtypeをcount_distinctにしておくこと
      timeframe: month
    }
    materialization: {
      increment_key: created_month
      sql_trigger_value: SELECT MAX(created_date) FROM WH.schema.orders
    }
  }
}

PDTとの違い

PDT(Persistent Derived Table)はLookerが管理する一時的なマテリアライズドテーブルで、特定のSQLを事前に実行しキャッシュしておく手法です。一方、集計認識は「Lookerがユーザーのクエリから自動的に最適な集計済みテーブルを選ぶ」仕組みであり、PDTはあくまで集計認識の1つの実現手段にもなり得ます。つまりはユーザーが「これとこれとこれ」を使って「集計結果を見たい」という要望があったときに、「実は元から用意してたんでこれどうぞ」というような用意周到な執事のようなことをLookerが自動的にやってくれるということです。

比較とまとめ

特徴 PDT 集計認識
基本概念 手動で定義したSQLを事前計算 複数の集計テーブルから自動で最適選択
テーブル選択 ユーザー/開発者が定義や設定 Lookerがクエリ内容に基づき自動判断
運用コスト PDT構築・再計算管理が必要 粒度別テーブルを定義すればLooker任せ
パフォーマンス 適切なPDTで高速化可能 複数粒度テーブルでさらに柔軟かつ自動最適化
適用シナリオ 特定の事前集計が必要なケース 同一指標の複数粒度集計を効率的に提供したい時

まとめ

PDTが一種の「特定用途の事前計算キャッシュ」として機能するのに対し、集計認識は「Lookerが複数の集計テーブルを状況に応じて使い分ける」高度な最適化手法です。
大規模データで異なる粒度の分析が多い環境では、集計認識を導入することでユーザー体験・処理効率が大きく改善します。

もしユーザーの要望がすでに明確化していてそれに対しての迅速な処理と結果の表示を求める場合は、この集計認識は非常に有効な手段です!
ぜひご検討ください。

次はLiquid parameter(リキッドパラメーター)について

Discussion