MySQLを使用するメリットの一つは、何百万、何千万もの大量のレコードを持つ巨大なテーブルを扱えること。 ところが、そうした巨大テーブルをFileMaker アプリから操作しようとすると、大きな問題にぶつかる。(尚、下記の環境は、クライアントからFileMaker Server上のアプリファイル(NekoApp50.fp7)にアクセスしている。ローカルでNekoApp50.fp7を実行すれば、実行速度は改善される。)
問題1. だらだらクエリ
例えば、12万件のレコードを持つ郵便番号テーブルをFileMaker のレイアウト上に表示し、一番最後のレコードに移動してみる。移動すると「検索実行中... クエリーを処理中」と数十秒またされることになる。これはMySQLのログを見てみるとわかるが、
SELECT DISTINCT ID FROM vw_zips WHERE ID>19 ORDER BY ID
SELECT DISTINCT ID FROM vw_zips WHERE ID>1019 ORDER BY ID
SELECT DISTINCT ID FROM vw_zips WHERE ID>2019 ORDER BY ID
SELECT DISTINCT ID FROM vw_zips WHERE ID>3019 ORDER BY ID
・・・
・・・ 中略
・・・
SELECT DISTINCT ID FROM vw_zips WHERE ID>119019 ORDER BY ID
といったクエリをテーブルの全レコード件数(この例では12万件)に達するまで延々と発行し続け、FileMakerにこれまた延々とロードし続ける、という仕様なのである。 実務上、これではユーザから苦情が来るのは必至。 さらに、テーブルデータが100万、1000万件に達する場合は、実用に耐えない。
尚、一度ロードしてしまえば、アプリを閉じるまで、上記の『だらだらクエリ』は実行しないようである。
問題2. 検索を実行すればするほどデータの並びがグチャグチャに?
FileMakerはクエリを実行した順にデータをロードし、一旦ロードされると再ロードは行わない。ユーザの検索実行数が増せば増すほど、レコードは作成順に並ばず、グチャグチャに並んでるように見える。
例えば、郵便番号レイアウトを開くと、FileMakerはそのレイアウトに割り当てられたテーブル(レイアウトテーブル)のレコードの1番目から数十番目までをSELECTする以下のようなクエリを実行し、レイアウト上に表示する(SELECTされるレコード数は、レイアウトの形状、ウインドウの大きさにより異なる)。
SELECT ID,`〒`,`住所` FROM 郵便番号 WHERE ID IN (1,2,3,4, ~中略~ ,26,27)
次に、ユーザ自ら郵便番号の「9071801」(沖縄県)を検索し、次に「2010004」を検索し、その後レコードメニューから「全レコードを表示」を行うと、以下のような並びになってしまう。
郵便番号「2010004」の後に「0600012」移行が並ぶのは、上記の「全レコード表示」の直後にスクロールダウンした為、SELECT ID,`〒`,`住所` FROM 郵便番号 WHERE ID IN (28,29,~,40,41)というクエリが実行され、該当するレコードがロードされた結果だ。
FileMaker は内部の SELECTクエリを実行した順にレコードをロードする。 再度検索を行っても、プライマリキーが同じものは再ロードされない。 ユーザが該当件数が少ない検索条件を実行すればする程、レコードは作成順には並ばないため、ユーザからみればグチャグチャに見える。
問題3. レコード総数取得クエリ
SQLテーブルをレイアウトに最初にロードすると以下のクエリが走る。
SELECT COUNT(*) FROM (SELECT DISTINCT ID FROM vw_salesdtls) COUNTER_TABLE
この SELECT DISTINCT には時間がかかり、180万件のテーブルだとレイアウトにレコードを表示するだけで30秒程度はかかってしまう(但し、一旦レイアウトテーブルをロードすると、アプリファイルを閉じるまで、このクエリは再発行されない)。巨大なテーブルを扱う場合は、VIEWによりレコード総数を制限する必要がある。
問題3については、数百万レコード程度であれば、ユーザも我慢できるかもしれないが、1と2ついてはなんらかの対応が必要だろう。
土屋
関連リンク:
『売上猫くん on MySQL』開発日記の記事一覧