スピードアップのための徹底チューニング

これまで何回か紹介してきたとおり、FileMakerをデータベースとしたWebアプリは、なにも考えずに実装してしまうとパフォーマンスが出にくい。ほかのデータベースでは一瞬で終わるような検索でも、FileMakerなら数秒~数分も待たされることがままある。

FileMakerでは「テーブルオカレンス」「自己リレーション」「計算フィールド」「集計フィールド」「スクリプト」といった、やや独自色の強い考え方がいくつもある。FileMaker Proでは「惰性で何気なく使っていた」実装方法も、Webアプリケーション上で場面を考えずに安易にこれらのテクニックを使用してしまうといつの間にかボトルネックになっていたということもある。しかし、これら「やっていい事」「やってはいけない事」を区別して場面ごとに適切な実装をおこなえばFileMakerのメリットを最大限発揮できるWebアプリケーションを実装することが可能となるのだ。

これまでに取りあげてきた内容と比較すると突っ込んだ話になるが、なるべく「簡単に」「どんな場面でも適用しやすい」「すでに実装したWebアプリにも適用可能」な範囲内でいくつかのノウハウを紹介していこう。

スピードアップのための、フィールド配置法

スピードアップのための徹底チューニング、第1回目は「フィールドの配置法」を取りあげよう。ここでのフィールド配置は、PHP側でのユーザインタフェースではなく、FileMakerのレイアウトに配置するフィールドのことを指す。

XMLでのカスタムWeb公開とFX.phpを使用したFileMaker Webアプリでは、FileMakerサーバとPHPの間でXMLデータを使用して通信をおこなっている。XMLデータはFX.phpから発行される各種クエリコマンドとパラメータによって形式が変化する。そして重要なポイントとして、XMLデータには処理中最後に表示していたレイアウトに表示されたレコードと、配置されているフィールドの内容が含まれる。

XMLデータにはフィールドの名称やFileMakerで設定した入力値の制限といったオプション、対象レコードの内容が「レイアウトに配置されているフィールド分」だけ格納される。このXMLデータのサイズを極力小さなサイズにできるように心がければ、スピードアップが期待できる。一番効果を発揮できるのは「一覧画面」といった、すべてのフィールドを表示する必要がない場面だ。実際に必要なデータだけをやり取りすることで、どれだけの改善がはかれるかを試してみよう。使用したFileMakerファイルの情報は次のとおり。

テーブル「fm_tune」。シリアル・登録日時・更新日時のほかに「テキスト」「数値」「日付」タイプのフィールドをそれぞれ10個作成している

レイアウト「fm_tune」。テーブル内のフィールド33すべて配置している。それぞれのフィールドには「フィールド名」「Random関数の実行結果」「2009/6/22」を格納した

レイアウト「fm_tune_list」。タイプがことなるフィールドより2つずつを配置し、計9フィールドが配置されている。

場面ごとにレイアウトを切りかえることでどれだけのスピードアップが望めるかを確認してみよう。ここでは確認にあたり、Apache Bench(ab)を使用して計測をした。requestsは100、concurrencyは3にセットしている。

レイアウト「fm_tune」へのアクセス結果

% ab -n 100 -c 3 -A admin:admin "http://localhost/fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_tune&-max=30&-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_tune&-max=30&-find
Document Length:        42057 bytes

Concurrency Level:      3
Time taken for tests:   6.254 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      4244200 bytes
HTML transferred:       4205700 bytes
Requests per second:    15.99 [#/sec] (mean)
Time per request:       187.621 [ms] (mean)
Time per request:       62.540 [ms] (mean, across all concurrent requests)
Transfer rate:          662.73 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.4      0       3
Processing:    98  186  40.2    190     297
Waiting:       37   80  28.2     75     161
Total:         98  186  40.2    190     297

Percentage of the requests served within a certain time (ms)
  50%    190
  66%    202
  75%    208
  80%    214
  90%    235
  95%    258
  98%    290
  99%    297
 100%    297 (longest request)

レイアウト「fm_tune_list」へのアクセス結果

% ab -n 100 -c 3 -A admin:admin "http://localhost/fmi/xml/FMPXMLRESULT.xml?-db=fm_tune.fp7&-lay=fm_tune_list&-max=30&-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_tune_list&-max=30&-find
Document Length:        12524 bytes

Concurrency Level:      3
Time taken for tests:   3.208 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      1290900 bytes
HTML transferred:       1252400 bytes
Requests per second:    31.17 [#/sec] (mean)
Time per request:       96.233 [ms] (mean)
Time per request:       32.078 [ms] (mean, across all concurrent requests)
Transfer rate:          393.00 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       2
Processing:    52   96  23.6     93     165
Waiting:       42   80  22.8     77     144
Total:         52   96  23.6     93     166

Percentage of the requests served within a certain time (ms)
  50%     93
  66%    105
  75%    111
  80%    114
  90%    132
  95%    140
  98%    153
  99%    166
 100%    166 (longest request)

localhostへのアクセスなので正確な結果ではないものの、これらの結果からおおよそ2倍ほどのスピードアップが望めることが確認できた。とくに意識していないと一覧画面も詳細画面もデータ保存に使用するレイアウトも一緒くたにしてしまいがちだが、レイアウトに配置するフィールドを整理するだけでも、これだけの差が出る。レイアウトの管理が若干面倒になるが、得られるスピードを考えると管理の手間を差し引いても充分なおつりがくるだろう。肥大化したシステムでは必須のテクニックと言える。

フィールドの配置について、注目するポイントは次のとおり。

  • 必要のないフィールドは配置しない(とくに非保存の計算フィールドや集計フィールド)
  • 必要のないポータルは配置しない。どうしても必要な場合は、専用のリレーションを組み必要最低限のレコードしか取得しないように構成する

非保存の計算フィールドや集計フィールドを使うことでのスピード低下は追って紹介していこう。なお、FX.phpの場合はSetDBDataの第4引数にこの「レスポンスレイアウト(-lay.response)」が指定できるようになっている。すでにFX.phpを使用したWebアプリがある場合は、該当箇所の第4引数に整理したレイアウトを指定するだけでスピードが違ってくるはずだ。必要なときに必要なだけの情報を取り扱うように心がけ、少しでもスピードアップできるように実装していこう。