Fast Summary再考

今回は、「バーチャリストによるレポート生成」(パート1, パート2)で使用していた高速な集計処理の手法の一つであるMulti-Findを、その他の手法と比較しながら解説した記事をご紹介します。


FileMaker Hacks logo

Fast Summaries Revisited

(元記事はこちら)

Kevin Frank
2016/3/30

複雑なデータ分析をする場合、データをグループ化・集計・解析して、その結果を変数やフィールドに入れるという操作をおこなうことがよくあるでしょう。これを実現する方法はいくつかありますが、その中の一つであるFast Summaryというテクニックは、このブログにここ何年かで 何度か取り上げているので、いつも読んでいる読者の方はご存知だと思います。

今回はFast Summaryに替わる手法を紹介していきます。デモファイルを使って、ぜひ実際に手元でベンチマークをしてみてください。

2016-03-29_223920

自分ではベンチマークをしないという方は、スクロールして以下に掲載している私のテスト結果を参照してください。
ポイントは、紹介する3つの手法は、どれがもっとも高速に動作するかが条件によって変わるということです。

(「スクリプトをサーバで実行(Perform Script On Server; PSOS)」をまだ試したことがないという方は、ぜひデモファイルをFileMaker Server 13以降のサーバでホストしてください。 レポート作成スクリプトの一部はPSOSを使用しているので、この隠れた機能に今からでも無理なく入門することができるでしょう。

アドホックな検索 vs 構造化された検索

説明を進める前に、「アドホック」な検索と「構造化された」検索の違いを明確にしておきます。「アドホック」とは、処理を行う対象レコードのセットが、スクリプトのような予め構造化されたものではない操作によって生成されるものを言います。具体的には、検索/対象レコードの拡大/対象レコードの絞り込み/対象外にする、などの手作業の操作を組み合わせて対象レコードを特定する処理です。言い換えると、検索条件が予め決まっていない場合です。

この区別を明確にする理由は、最初にアドホック検索を行う場合、Fast Summaryの手法の方がこれから試そうとするいずれの手法よりも高速だからです。そんなことを言ったら読者の方はここで読むのをやめてしまいそうですが。(誤解のないようにいうと、他の手法も上記のような任意の対象レコードに対して行うことができますが、処理にかかるコストは許容されないほどに高くなります。)

一方で、解析や集計をおこなう対象のレコードが、「構造化されている」と言われる範疇の方法(例えば、注文を販売会社・月・年ごとに集計、売り上げを地域・担当者ごとに集計、Webページへのアクセスを週・年で集計、顧客をタイプ[店頭/電話/Web]ごとに集計、など)で処理される場合は、このまま読み進めていただいて、この圧縮ファイルの中のデモファイルを試してみてください。

Fast-Summaries-Revisited.zip (10Mb, FMP 13以降が必要)

2016-03-30_164248.png

基本的な考え方

各デモファイルは、同じ結果を導き出すために、複数の手法を使います。注文テーブルのレコードを販売会社ごとにグループ化して集計し、組み立てた結果をまず変数に入れ、最終的には以下のような集計レポート用の1つのフィールドに格納します。

2016-03-29_232144

テストを実行するには、デモファイルを開いてこれら3つのボタンのいずれかをクリックしてください。

2016-03-29_233217

キャッシュのせいで誤った結果が出るのを避けるため、各テストごとにデモファイルを閉じて開き直すことをお勧めします。また、ファイルをFileMaker Server 13以降でホストすれば、以下のオプションを選択することができます。

2016-03-29_232937

選択が結果画面に反映されます。

2016-03-29_2342
サーバサイド

手法

A. Fast Summary (FS)

B. Multi-Find (MF)

  • 会社IDのリスト(社名順にソート)を取得する
  • このリストをループし、IDごとに検索をおこない、集計値を変数に入れる
  • 変数の値を合計してグローバルのテキストフィールドに入れる

C. Global Relationship (GR)

  • 会社idのリスト(社名順にソート)を取得する
  • リストをループし、注文テーブルの2つ目のオカレンスとの間にリレーションを設定したグローバルフィールドに各IDを追加していく。このリレーションシップで取得される値をカウントあるいは集計し、変数に格納する
  • 変数の値を合計してグローバルのテキストフィールドに入れる

注:これら3つの手法のコードは、スクリプト「sub: generate report」で確認できます。

テスト結果

すべてのテストはFMP 14とFMS 14を使用しておこなわれました(FMS 14を使用した部分はその旨記述あり)。「SERVER SIDE」はPSOSを使用したことを意味し、「CLIENT SIDE」はPSOSを使用していません。

2016-03-30_121623

注:スクリプト「create order entries」を実行することで、簡単に好きなだけ注文レコードを追加できます。画面に従って、追加するレコード数・開始年、終了年を指定してください。

以前のテスト結果

(WAN利用時のベンチマーク[PSOSとGlobal Relationshipは除く]。併せてFMP 13とFMP 14の性能比較)

2016-03-30_182315

SQLの場合は?

2016-03-30_004438

残念ながらSQLは今回の課題には向いていないようです。ぜひ自身でも試してみてください。

結論

言うまでもないことですが、これらのデモは意図的に単純化したものであり、実環境の複雑な条件は反映されていません。それでも、一定の条件のもとであれば、何らか実装時に参考となる結論が導き出せると思います。

1. Fast Summaryの手法は対象レコードを高速に走査できるが、集計するレコードを予めソートしておく必要がある。これは対象レコードの大きさによっては、直接的にパフォーマンス上のマイナスになる。(前出の『「アドホック」な検索 vs 「構造化された」検索』のコメントを参照)

2. 適度なレコード数、具体的にはローカルで処理する場合は5,000〜40,000件程度、LANのクライアント側で処理する(つまりPSOSを使わない)場合は80,000件までであれば、Global Relationshipの手法が最も速い。

3. より多数のレコードの場合、あるいはサーバサイドで処理する場合(ただしレコード数が極端に少ない場合を除く)は、Multi-Findが最も速い。

Leave a Reply