dely Tech Blog

クラシル・TRILLを運営するdely株式会社の開発ブログです

木も見て森も見るための Athena(Presto) 集計術

こんにちは!

今年、dely株式会社に新卒入社した開発本部のGENです。

この記事は「dely #1 Advent Calendar 2020」の2日目の記事です。

「dely #2 Advent Calendar 2020」はこちら↓

昨日はmochizukiさんの「Ruby 3.0へ向けて、型周りをさわってみた」という記事でした。 記事で使用しているレシピのチョイスも最高なのでみてみてください!

今回は Athena(Presto) でアクティブユーザ(DAU,WAU,MAU)の推移を長期間でみるための集計術を紹介したいと思います。 

アクティブユーザ集計における木も見て森も見るとは

「木を見て森を見ず」と言うことわざの意味を eigobu.jp で見てみると「細かい部分にこだわりすぎて、大きく全体や本質をつかまないこと」でした。アクティブユーザ集計(DAU,WAU,MAU)における「木を見て森を見ず」とはどういった状態かというと、「短期的な数値の増減を意識しすぎて、長期的な数値の増減の変化を考えられていない状態」です。ここから「木も見て森も見る」を考えると「短期的な数値の増減も意識しつつ、長期的な数値の増減の変化を考える状態」ということになります。

短期間での集計方法

例えば、以下のようなデータ(添付したものはデータの一部を抜粋したもの)が入っているテーブルがあります。

launchテーブル

このときに10日前から昨日までの各日付ごとに DAU,WAU,MAU を集計するとなると、window 関数を用いる手法が思いつきますが、DISTINCT と ORDER BY は同時に用いることができないためエラーが出てしまいます。それを加味した上でクエリを書くと以下のようになります。

これを1年間といった長期間で集計を行おうとすると、クエリの実行がタイムアウトになってしまいます。このようになる原因は JOIN するデータ量が多くなりすぎて処理に時間がかかってしまうことが考えられます。

長期間の集計で使用した手法

集計する手順は以下のようになります。

  1. user_id ごとに launched_date を格納した array を用意
  2. 各ユーザごとに CARDINALITY を用いて対象の期間に launch しているかを求める
  3. launch したユーザ数を集計

これをクエリに書いてみると以下のようになります。

launched_date ごとに user_id を array に格納するパターンも試しましたが、恐らく array に格納できるリソースに限界があり、リソースエラーが発生してしまいました。

さいごに

明日はMeilCliさんの「【C#】null許容値型のnonnull判定どれが早いかクイズ」です。 お楽しみに!!

また、dely ではエンジニアを絶賛募集中です!

ご興味あればこちらのリンクからお気軽にエントリーください! https://join-us.dely.jp/

さらに TechTalk というイベントも行っているので、dely について詳しく知りたい方は是非参加してみてください!