この特集のトップページへ

Accessによるアプリケーション

 Microsoft社のOffice製品の1つであるAccessは,クライアントアプリケーションの作成に使用され,データベースサーバー上のSQL Server 7.0と協調して処理を実施する。Accessを使用して作成されたクライアントアプリケーションは,Windows 95/98上およびWindows NT Workstation上で動作する。このようなクライアントアプリケーションをチューニングするには,アプリケーションが動作する環境設定とアプリケーションのソースコードの両方を検証する必要がある。通常は動作環境設定を変更する必要はないが,Jetエンジンを利用したときには設定を変更しなければならないこともある。

 Access 97で作成したアプリケーションであればJetエンジンおよびODBCを経由してSQL Server 7.0にアクセスする方法しかないが,Access 2000からはJetエンジンを介することなく,OLE DBプロバイダ経由で直接SQL Server 7.0にアクセスすることができるので,新規にアプリケーションを開発するのであれば,Access 2000のほうがよいかもしれない。

 データベースへのアクセス性能を改善するためには,次のような点を検討する。

○データベースがサポートしている機能のみを使用する
 SQL Server 7.0でサポートされていない機能を使用した場合,その機能はローカルで処理される。たとえば,SQL Serverでは評価できない式が集計クエリ,DISTINCTクエリ,ユニオンクエリのSELECT句にあれば,そのクエリはローカルで評価される。同様に,WHERE句,ORDER BY句,GROUP BY句にSQL Serverで評価できない式がある場合は,クエリの一部がローカルで評価される。すなわち,SQL Serverに格納されているデータを利用して,Access固有の要素を含む式を処理する場合,Accessは式をローカルで評価し,必要なデータをSQL Serverから取得する。また,定数やクエリパラメータだけが式に含まれる場合,Accessは式を一度だけ評価し,結果をクエリパラメータとしてSQL Serverに送信する。一般的に,SQL ServerがインストールされているPCサーバーに比べると,PCクライアントのプロセッサの処理性能は低く,メモリも少ないことが多いので,クライアント側で余計な処理をさせると,その分だけクエリの処理速度は遅くなる。

○必要最小限のデータを要求する
 サーバーに格納されているデータを大量に要求すると,ネットワークトラフィックも増し,ロードされたデータの処理にも時間がかかる。必要最小限のデータを要求するために,次のような対策を検討する必要があるだろう。

  • フィルタあるいはクエリを使用してレコードセットのサイズを制限する
  • フォームで使用するフィールドのみを選択するクエリを実行する
  • リストボックスやコンボボックスのような連結コントロールの使用をできるだけ避ける

○パススルークエリを使用する
 パススルークエリを使用すると,入力されたTransact-SQLステートメントはAccessで解釈されることなくSQL Serverに直接送信され,受信したパススルークエリをSQL Serverが解釈して実行する。そのため,ローカルでクエリをコンパイルし,SQL Serverに送信して実行するより高速に応答が返される可能性がある。それが頻繁に実行されるクエリであれば,SQL Serverのキャッシュに保持されている可能性が高まり,毎回クエリ実行計画を作成するオーバーヘッドを削減することもできる。特に,更新・削除・追加など,処理の多いクエリを実行する場合には,アタッチされたリモートテーブルに対するアクションクエリを利用するより,パススルークエリを利用して一括処理を実行するほうが処理は高速になる。また,ネットワークトラフィックも少なくなる。高速で処理能力の高いPCサーバーで処理すれば,クエリの性能も向上する。

Fig.9-37 パススルークエリ


 しかし,パススルークエリで返されるレコードセットは,常にスナップショットタイプ*1であり,更新できないという欠点があることには注意したい。

○サーバーのテーブルとビューをAccessデータベースにリンクする
 SQL ServerのテーブルとビューをAccessデータベースにリンクすると,リンクしたテーブルの列およびインデックスの情報がローカルに保存されるため,テーブルをオープンするときの処理効率が向上する。特にODBC経由でデータベースにアクセスする場合は,テーブルをリンクするほうが処理は高速になる。ただし,SQL Serverの列やインデックスを変更したときには,リンクの更新が必要になる。ビューはインデックスのないリンクテーブルとして扱われ,ビュー内で定義されている処理は常にSQL Server上で実行されるため,性能が向上する。

○サーバーから返されるデータを一時的にローカルで格納する
 SQL Serverから返された少数のデータを頻繁にくり返し利用するのであれば,ローカルテーブルに一時的にそのデータを格納する。それによって,SQL Serverの負荷やネットワークのトラフィックを軽減させることができる。また,データ量が少なく,検索表示のみでデータの変更を伴わない場合には,ローカルのデータベースに格納することも効果的である。ただし,クエリのなかでリモートのテーブルと結合する必要がある場合には,異種結合*2を避けるために,同じテーブルをSQL Serverにも格納する必要がある。もしデータを変更したのであれば,SQL Serverからデータをダウンロードする。

○リモートテーブルにTimestampフィールドを追加する
 テーブルにTimestampフィールドが定義されている場合,AccessはレコードのTimestampフィールドを調べてレコードに変更があったか否かを調べ,処理を実施する。この結果,レコードの無用な更新を避けることができ,処理を効率化することができる。

○トランザクションを使用する
 Jetエンジンに対してトランザクションを使用すると,複数ユーザーが同一データに対して同時に利用したとき,複数の更新処理をいったんローカルにキャッシュしてバッチとして一括処理する。そのため,ディスクI/Oの回数を軽減し,更新処理を効率化することができる。

○リモートデータのキャッシュ
 リモートデータに基づくデータシートやフォームでは,データが自動的にキャッシュされる。しかし,Visual Basicで作成されたダイナセット*3はキャッシュに保存されない。レコード数が200件未満の小容量のデータをくり返し参照する場合は,CacheSizeプロパティおよびCacheStartプロパティを利用し,明示的にデータをキャッシュへと保存することで,処理を高速化することができる。

○ODBCDirectあるいはOLE DB
 ODBCDirectあるいはOLE DBは,Jetエンジンを介さずにクエリを直接データソースに送信し,結果セットも同様に直接受信する。したがって,Jetエンジンを利用する場合と比較すると,処理が高速になる。しかも,非同期クエリを実行できるので,データベースサーバーの処理の完了を待たずに別の処理を実行することができるという利点もある。

 Accessのフォームは大量のリソースを消費するため,アプリケーションのロードや実行速度が低下するという欠点を抱えている。フォームに含まれるコントロールはフォームをロードするときに一緒にロードされるため,コントロールの使用数が増えれば増えるほどフォームのロード時間も長くなる。見栄えを追求して画面設計を進めると,性能やコードの最適化を犠牲にすることもある。

 フォームのロード時間を短縮したり実行速度を高速化したりするためには,フォームを使用しないことが最も安直な選択といえる。だが,実際のアプリケーション開発では,ユーザーの操作性を向上させたり誤操作を防止したりする観点から,フォームの利用は避けられない。したがって現実には,フォームそのものを利用しないというよりは,フォーム上で利用するコントロールの数を減らしたり,数を減らすことができなければコントロールを複数のページに分割配置させたりして,コントロールを同時に表示する機会を少なくすることになるだろう。

 また,フォームのダウンロード時間を短縮するには,必要なフォームのみを必要なときにダウンロードさせればよい。しかし,この方法だとアプリケーションの実行中に適宜フォームをダウンロードすることになるため,アプリケーションの実行時間は遅くなるというトレードオフもある。

 フォームのロード時間を短縮させたり実行速度を高速化させたりするためには,一般的に次のような手法を検討する。

○リストボックスやコンボボックスがリモートデータに基づいて一覧表示する場合は,スナップショットを使用する
 コンボボックスは,選択値を一覧表示し,そこから値を選択したり,あるいは一覧にない値を入力したりすることができる。ただし,フォームにスペースの余裕があり,常に一覧を表示する場合,または一覧のなかから値だけを入力する場合は,コンボボックスではなくリストボックスを使用するほうがよい。ウィザードを使用してリストボックスやコンボボックスを作成すると,コントロールのRowSource(値集合ソース)プロパティに対して自動的にSQLステートメントが作成され,そのSQLステートメントを実行してコンボボックスあるいはリストボックスに選択できる値の一覧が表示される。このような処理では通常,その値を更新する必要がないので,スナップショットタイプのレコードセットでよいことになる。そのほうが,ポインタを格納してそこからデータを取得するダイナセットタイプよりも処理が高速になる。

○リストボックスとコンボボックスには必要なフィールドのみを表示する
 RowSourceプロパティで指定したクエリに,必要なフィールドだけが含まれるようにする。それ以外のフィールドが多量に含まれる場合には,ネットワークトラフィックが増加し,性能が低下する場合がある。何度も説明しているように,不要な列は取得しないことが重要である。

○更新する必要がなく,レコードセットに含まれるレコード数が500件以下ならば,スナップショットに基づいてフォームを作成する
 少数のデータを参照するだけであれば,フォームのレコードセットプロパティにスナップショットを設定することにより,フォームのオープン時間を短縮でき,処理効率も向上する。ただし,多量のデータを参照する,あるいは更新する場合,あるいは参照するレコードセットにメモ型やOLE(Object Linking and Embedding)型のオブジェクトフィールドが含まれている場合は,各レコードの主キーのみを取得するダイナセットを使用するほうが高速になる。

○要求時にのみフィールドを表示する
 メモ型やOLE型のオブジェクトフィールドは,SQL Serverからのロードが必要になり,表示が完了するまでに時間がかかる。フォームの処理効率を向上させるためには,これらのフィールドの表示をできるだけ避けるか,最も重要なフィールドのみを表示するにとどめる。

○グラフィックオブジェクトの数を減らす
 フォームで使用される罫線や境界付きコントロールなどのグラフィックオブジェクトは,それぞれ独立したビットマップとして扱われるため,表示や印刷に時間がかかる。できるだけ不要なグラフィックオブジェクトは使用しないように設計する。どうしても表示する必要があるならば,ビットマップに変換してから表示すると,フォームのロード時間を短縮することができる。

○イメージコントロールを使用してビットマップを表示する
 イメージコントロールを使用してビットマップを表示することにより,フォームのロード時間やページ処理の効率を向上させることができるし,リソースの消費も軽減できる。オブジェクトフォームコントロールはシステムリソースを消費するので,OLEオブジェクトをアクティブにする必要がなければ,できるだけイメージコントロールを使用したほうがよいだろう。

○プロパティは必要なときにのみ設定する
 フォームやレポートでのコントロールプロパティの設定や変更には時間がかかる。プロパティを設定する場合には,その時点で設定されている値を調べて,必要があれば再設定するほうが効率がよい。


  1. スナップショットタイプのRecordsetオブジェクトは,クエリの実行結果のデータコピーを保持する。したがって,直接的にも間接的にも,元のテーブルとリンクされていないので,コピーを更新することはできない。更新する場合は,テーブルタイプのRecordsetオブジェクトまたはダイナセットタイプのRecordsetオブジェクトを使用する。
  2. ローカルテーブルとリモートテーブルとのあいだ,あるいは異なるODBCデータソースのリモートテーブル間の結合を指す。
  3. データベースのデータを操作するために使用するRecordsetオブジェクトの1つ。元のテーブルの情報へのポインタを返す。データが必要になったとき,そのポインタを使用してデータを取得する。そのため,更新処理が可能であり,ほかのユーザーが加えた変更も,挿入を除いてすぐに参照できる
前へ Chapter 9 17/46 次へ