大規模データの集計アンチパターン
大規模化するデータを相手取って集計を行う場合、対象となるレコードは数億〜数兆レコード以上であることは珍しくありません。
実データを確認するにしても理解できるのはせいぜい数百〜数千レコード程度です。
統計値などを通すことでより広い認知を獲得することができますが、データの複雑性を一定以上を超えるとひとつひとつのケースで解釈可能でも全体として人間が認知不可能な状況が生まれます。

大規模データに対する集計作業はこのような不確実性を抱えながら取り組むことになります。
この不確実性に気づかずに分析を行ってしまうことと、正確性が求められる分析に不具合をもたらすことになります。

この記事ではそれらをアンチパターンとして紹介していきます。

whereでなるべく絞り込まない


前提として あるページについて特定の条件にある時のページビュー数を知りたいという分析要件があるとしましょう。
その際には分析者は awesome_event_data 上のデータに対して次のような集計用のSQLを書くことになると思います。

with report as (
  select 
   page_id
   , count(1) as n_record
  from
    awesome_event_data
  where 
    awesome_attr = "something attr"
  group by page_id
)

select * from report

awesome_event_data に対する完全な知識があれば、このクエリ自体を書くことは特に問題ないのですが、この結果を分析結果と利用していくと次のような問題点が後々生じます。

  • awesome_attr で指定した条件が適切かどうか判断する材料がない
  •  n_recordが他と比べて多いのか少ないのか、比較の材料を持つことができない
  • その結果、集計結果の妥当性が判断できない
  •  awesome_attr="something attr" という条件は分析意図の特定の条件に対して、過剰な条件ないしは不十分な条件になっている可能性がありうる

データに対する知識の不確実性を仮定する場合において、whereに指定した条件が何をもってして必要十分な条件であるか判別するには、ドメイン知識という形で事前知識として知るほか根本的な対処する術がありません。
そのようなデータに対して不確実性を仮定する上で、ある程度の妥当性を確認しつつ進めるためには
対象のデータと共にその対象を取り巻くコンテキストを同時に集計するようにしましょう。

今回の場合ではwhereによる絞り込みを避け group by などを通して集計して
他の属性と比較可能な集計結果を保持しにしておくことが手戻りも少なくなるコツです。

先ほどのクエリは、次のように書き換えると良いでしょう。

with report as (
  select 
   page_id
   , count(1) as n_record
  from
    awesome_event_data