【テクニカル・上級編】ADOのCursorLocationプロパティがパフォーマンスに与える影響:Client vs Server – Access VBA解析バイブル

スポンサーリンク

Access VBAの深淵:ADO CursorLocationが支配する「メモリ」と「ネットワーク」の最適解

Access開発において、DAOは標準的だが、外部DBやWeb APIとの疎通、あるいは大規模データ処理においてADO(ActiveX Data Objects)を避けて通ることはできない。しかし、多くのエンジニアが `CursorLocation` の設定をデフォルトのまま放置し、結果としてアプリケーションのパフォーマンスを腐敗させている。

本稿では、`adUseServer` と `adUseClient` の本質的な違いを、単なるマニュアルの引用ではなく、メモリ管理とトラフィック制御の視点から解剖する。

—

1. adUseServer:データベースサーバーへの「直結」

`adUseServer`(サーバー側カーソル)は、DBサーバーのリソースを最大限に活用する。

  • 動作原理: レコードセットのポインタはサーバー上に置かれ、データは必要に応じてその都度フェッチされる。
  • メリット:
  • 初回応答速度: 全データを転送しないため、巨大なテーブルでも瞬時に開ける。
  • リアルタイム性: 他のユーザーの変更が即座に反映される(ロック設定に依存)。
  • 代償:
  • 接続の占有: レコードセットを閉じない限り、サーバー上の接続(コネクション)を掴み続ける。
  • ネットワーク負荷: ページ送りや検索を行うたびに通信が発生し、ネットワークのレイテンシ(遅延)に極端に弱い。

2. adUseClient:ローカルメモリへの「全権委譲」

一方で `adUseClient`(クライアント側カーソル)は、サーバー上のデータをごっそりとローカルメモリ上に引き抜く。

  • 動作原理: `Recordset` が開かれた瞬間に全データをクライアント(Accessのプロセス内メモリ)へ転送し、以後の操作はメモリ上で完結する。
  • メリット:
  • 高度な機能: `Filter` や `Sort`、`Find` といったクライアントサイドの強力な機能が使用可能。
  • ネットワーク解放: データ転送完了後は接続を閉じてしまっても、メモリ上のデータを操作できる。
  • 代償:
  • メモリ肥大化: 数百万レコードを読み込めば、Accessは容易にフリーズする。
  • 初回読み込みの重さ: 全データが到達するまで処理がブロックされる。

—

3. 実践:最適化された接続とオブジェクト管理

レガシー環境で最も避けなければならないのは、メモリリークと接続の放置だ。以下のコードは、`adUseClient` を使用しつつ、リソースを極限までクリーンに保つアーキテクチャの雛形である。

‘ 伝説的なパフォーマンスを維持するためのADOハンドリング
Public Sub ExecuteOptimizedQuery(ByVal sql As String)
Dim conn As Object
Dim rs As Object

Set conn = CreateObject(“ADODB.Connection”)
Set rs = CreateObject(“ADODB.Recordset”)

‘ 接続設定:タイムアウトを制御し、ネットワークの異常を許容しない
conn.ConnectionTimeout = 15
conn.Open “Provider=SQLOLEDB;Data Source=ServerName;Initial Catalog=DBName;Integrated Security=SSPI;”

‘ クライアントカーソルでメモリ上に展開し、サーバー接続を最短で解放する
rs.CursorLocation = 3 ‘ 3 = adUseClient
rs.Open sql, conn, 3, 3 ‘ 3, 3 = adOpenStatic, adLockOptimistic

‘ 接続を切断しても、adUseClientならデータはメモリに存在する
Set rs.ActiveConnection = Nothing
conn.Close

‘ — ここでデータ加工を高速に行う —

‘ 終了処理:参照の明示的解放(オブジェクトのライフサイクルを制御)
If Not rs Is Nothing Then
If rs.State = 1 Then rs.Close
Set rs = Nothing
End If
Set conn = Nothing
End Sub

—

4. チーフアーキテクトからの提言:使い分けの指針

実務においてどちらを選択すべきか。判断基準は明確である。

1. adUseServerを選ぶべき時:

  • 数万件以上のレコードを扱う場合。
  • 頻繁に動的な検索(`WHERE`句の変更など)をサーバー側で行う必要がある場合。
  • 同時実行性が高く、他者による更新を即座に感知したい場合。

2. adUseClientを選ぶべき時:

  • レコード数が数千件以下で、メモリ上に収まる場合。
  • ネットワーク環境が不安定な場合(接続を即座に切断できるため)。
  • 複雑な並び替えや、VBA側で高度なデータ操作(フィルタリング等)を多用する場合。

最後に:Windows APIの活用について

もし大規模なデータ処理中にAccessがメモリを解放しない事象(いわゆるVBAのGCの弱さ)に直面した場合は、`SetProcessWorkingSetSize` APIを呼び出し、強制的に空きメモリをOSへ返還させる手法が有効だ。しかし、これは「対症療法」に過ぎない。

真のエンジニアは、`CursorLocation` を適切に設定し、不要な接続を `Nothing` にする。アーキテクチャを理解した上でコードを書くこと。それが、あなたのシステムをレガシーの呪縛から解放する唯一の道である。

タイトルとURLをコピーしました