FileMakerを使用したアプリケーションの構築に不可欠な「計算フィールド」と「集計フィールド」。計算フィールドではビルトインの関数を使いこなし、簡単なものから複雑なものまで自由に数式を組み、簡単に計算結果を得ることができる。集計フィールドも簡単な操作で合計・平均値・標準偏差・合計に対する比といったさまざまな切り口で集計結果を算出する事が可能だ。FileMakerの開発において、工数を縮める一つのキーと言っても過言ではないだろう。
たいへん便利なこの2タイプのフィールドだが、Webアプリケーションではこれらのフィールドの取り扱いを間違えると大幅な性能低下の原因となる、要注意のフィールドだ。本稿では2回にわけて、これらのフィールドを使う事での性能低下と、性能低下を回避する実装手段を紹介しよう。1回目はおもに「計算フィールド」について取りあげる。
非保存の計算フィールドで検索をおこなうことでのスピード低下
やや規模の大きいアプリケーションをFileMakerで作成したことのあるデベロッパならすでにおわかりかと思うが、計算・集計フィールドはレコード数が多ければ多いほど、動作スピードが鈍化する。とくに計算フィールドにおいては、リレーションシップフィールド(ほかのテーブルのフィールド)を数式に含め、索引が生成できない状態で検索をおこなったときに大幅な速度低下・サーバマシンへの過負荷がおこる。FileMakerの検索画面で検索実行後「クエリーを処理中...」ダイアログが何分間も出ている場合は、十中八九この索引が作れないフィールドにたいしての検索がおこなわれていると思っていいだろう。
もちろんこのスピード低下はWebアプリケーションでも発生する。ためしに索引を作る計算フィールドと索引を作らない計算フィールド、リレーションシップフィールドをふくめた計算フィールドを作成し、該当フィールドにたいして検索を実行、その結果を比較してみよう。
作成した3フィールドは次のとおり。
- fm_calcField: すべて索引を設定する。計算式は「( f_numField_1 ) + ... ( f_numField_10 ) 」
- fm_calcField_noIndex: 索引を保存しない。計算式はfm_calcFieldと同様
- fm_calcField_useRField: 計算式内にリレーションシップフィールドを使用、索引は保存できない。計算式は「( fm_tune_self::f_numField_1 ) + ... ( fm_tune_self::f_numField_10 )」
検索に使用するレイアウトには、誤差をすくなくするためにそれぞれの計算フィールドを配置したレイアウトを作成した。レコード数は10,000件としている。
前回同様、Apache Bench(ab)を使用して計測を実施した。requestsは10、concurrencyは1にセットしている。
全索引設定の計算フィールド「fm_calcField」 - 検索実行結果
% ab -n 10 -c 1 -A admin:admin "http://localhost/fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_calcField&fm_calcField=%3C5&-find"
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: Apache/2.2.9
Server Hostname: localhost
Server Port: 80
Document Path: /fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_calcField&fm_calcField=%3C5&-find
Document Length: 1975 bytes
Concurrency Level: 1
Time taken for tests: 0.239 seconds
Complete requests: 10
Failed requests: 0
Write errors: 0
Total transferred: 23600 bytes
HTML transferred: 19750 bytes
Requests per second: 41.77 [#/sec] (mean)
Time per request: 23.939 [ms] (mean)
Time per request: 23.939 [ms] (mean, across all concurrent requests)
Transfer rate: 96.27 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 21 24 2.5 24 28
Waiting: 21 24 2.5 24 28
Total: 21 24 2.5 25 29
Percentage of the requests served within a certain time (ms)
50% 25
66% 25
75% 26
80% 26
90% 29
95% 29
98% 29
99% 29
100% 29 (longest request)
索引非保存の計算フィールド「fm_calcField_noIndex」 - 検索実行結果
% ab -n 10 -c 1 -A admin:admin "http://localhost/fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_calcField_noIndex&fm_calcField_noIndex=%3C5&-find"
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: Apache/2.2.9
Server Hostname: localhost
Server Port: 80
Document Path: /fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_calcField_noIndex&fm_calcField_noIndex=%3C5&-find
Document Length: 1991 bytes
Concurrency Level: 1
Time taken for tests: 30.050 seconds
Complete requests: 10
Failed requests: 0
Write errors: 0
Total transferred: 23760 bytes
HTML transferred: 19910 bytes
Requests per second: 0.33 [#/sec] (mean)
Time per request: 3005.002 [ms] (mean)
Time per request: 3005.002 [ms] (mean, across all concurrent requests)
Transfer rate: 0.77 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 0
Processing: 2944 3005 65.0 2992 3163
Waiting: 2944 3005 65.0 2992 3163
Total: 2945 3005 65.0 2993 3163
Percentage of the requests served within a certain time (ms)
50% 2993
66% 2998
75% 3000
80% 3069
90% 3163
95% 3163
98% 3163
99% 3163
100% 3163 (longest request)
リレーションシップフィールドを使用した計算フィールド「fm_calcField_useRField」 - 計算実行結果
% ab -n 10 -c 1 -A admin:admin "http://localhost/fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_calcField_useRField&fm_calcField_useRField=%3C5&-find"
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: Apache/2.2.9
Server Hostname: localhost
Server Port: 80
Document Path: /fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_calcField_useRField&fm_calcField_useRField=%3C5&-find
Document Length: 1995 bytes
Concurrency Level: 1
Time taken for tests: 99.652 seconds
Complete requests: 10
Failed requests: 0
Write errors: 0
Total transferred: 23800 bytes
HTML transferred: 19950 bytes
Requests per second: 0.10 [#/sec] (mean)
Time per request: 9965.216 [ms] (mean)
Time per request: 9965.216 [ms] (mean, across all concurrent requests)
Transfer rate: 0.23 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 9874 9965 91.4 9943 10169
Waiting: 9874 9965 91.4 9943 10169
Total: 9874 9965 91.4 9943 10169
Percentage of the requests served within a certain time (ms)
50% 9943
66% 9949
75% 9958
80% 10090
90% 10169
95% 10169
98% 10169
99% 10169
100% 10169 (longest request)
全索引設定をおこなっている計算フィールドのTime per request(1リクエスト当たりの平均処理時間)はわずか0.023秒だが、索引を設定していない計算フィールドは3.005秒、さらにリレーションシップフィールドを使用した計算フィールドについては9.965秒もの処理時間がかかっていることがわかった。そのパフォーマンス差はなんと100倍から400倍。索引を気にせず計算フィールドを作ってWebアプリケーションを構築してしまうと、同時ユーザなしの検索でもこれだけ処理時間の差がでる。ユーザ数の多いWebアプリケーションではさらに時間・負荷がかかってしまうことになるのだ。
検索を実装する上でのおさらい
これらの結果から、計算フィールドを用いたFileMakerファイルにおいて注意すべき点をまとめてみよう。
- 検索に使用するフィールドにはかならず索引を設定すること
- リレーションシップフィールドを使用するなどの理由で索引を作成できない計算フィールドに対しては検索を実行しない
- 計算結果が格納されたフィールドで検索をしたい場合は、「入力値の自動化>計算値を使用する」「データ格納時にスクリプトで計算結果を代入」といった方法で索引を設定できるフィールドで代用する
複雑なフラグ管理をともなう要件において、便利な計算フィールドは多用してしまいがちだ。しかし1歩間違えば、大幅な速度低下を招くことを忘れてはならない。