#33 DAOのレジストリチューニング(MaxBufferSize)

結論
Jetデータベースエンジンのレジストリの「MaxBufferSize」の設定値によって微妙にパフォーマンスが変わるが、大きければ大きいほどよいということはない。結局、MaxBufferSizeはデフォルト値のままが最適のようである。

Accessでレコードセットを扱うとき、そのパフォーマンスに与える要因には、キーの設定や正規化、フィールド構造、クエリ構造などのデータベース構造や、プログラム上のパラメータ(OpenRecordsetメソッドなど)などがありますが、今回は「Jetデータベースエンジン」そのものの設定を変えることによる影響を調べてみることにします。具体的には、Jetデータベースエンジンに関するレジストリのエントリを操作してみます。

Jetデータベースエンジンに関するレジストリのエントリは、以下の場所にあります。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Jet 4.0


このエントリの下位にあるすべてのキーに関してその意味を知っているわけではありませんが、パフォーマンスに関連していそうな項目として、今回は「MaxBufferSize」の値を操作してみます。

MaxBufferSizeは、Jetデータベースエンジンの内部キャッシュのメモリサイズをKB単位で設定するもので、デフォルトでは「0(ゼロ)」が設定されています。ただしこれは、単純にメモリサイズが0KBということではなく、Jetデータベースエンジンがパソコンの総メモリ容量などを判断して、自動的に任意のメモリサイズを割り当てる、つまりキャッシュのサイズをJetデータベースエンジンに任せるといった意味合いを持っています。


今回のテストでは、全部で3万件のレコードを持っているテーブルを先頭レコードから順番に読み取るというプログラムを走らせて、MaxBufferSizeの値をいくつか変えたときの処理時間を比較してみます。ここで使うプログラムは次のようなものです。


Dim dbs As Database
Dim rst As Recordset
Dim varDummy As Variant

Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("顧客マスタ")

With rst
  Do Until .EOF
    varDummy = !顧客ID
    varDummy = !会社名
    varDummy = !顧客の氏名
    varDummy = !顧客のシメイ
    varDummy = !支社名
    varDummy = !請求先住所
    varDummy = !市区町村
    varDummy = !都道府県
    varDummy = !郵便番号
    varDummy = !地域
    varDummy = !顧客の部署名
    varDummy = !電話番号
    varDummy = !内線番号
    varDummy = !FAX番号
    varDummy = !電子メールアドレス
    varDummy = !備考
    .MoveNext
  Loop
  .Close
End With



ここでは、単なるレコード移動だけでなく、すべてのフィールドが走査されるよう、varDummy変数に各フィールド値を代入する処理を交えています(あくまでも念のため)。また、Windows自体のディスクキャッシュなどの影響も考慮し、各テストパターンごとにパソコンを再起動し、その直後にAccessを起動、このプログラムを複数回実行するように留意しました。


テストパターンとしては、MaxBufferSizeの値を次の4つに変化させて、その処理時間を測定・比較します。キャッシュの効果は2回目以降の実行時に表れるはずなので、各条件ごとに5回同じプログラムを実行するものとしました。ちなみに、テストに用いたパソコンの総メモリは512MBです。

MaxBufferSizeの設定値
デフォルト値(0KB)
10MB
100MB
200MB


テスト結果は次のようになりました。
MaxBufferSize 回数 実行時間(秒) 前回との差異(秒)
デフォルト値 1回目 38.80 -
2回目 20.53 -18.27
3回目 6.17 -14.36
4回目 6.18 0.01
5回目 6.17 -0.01
10MB 1回目 35.65 -
2回目 22.47 -13.18
3回目 7.46 -15.01
4回目 7.80 0.34
5回目 7.55 -0.25
100MB 1回目 39.59 -
2回目 32.17 -7.42
3回目 7.69 -24.48
4回目 6.72 -0.97
5回目 6.65 -0.07
200MB 1回目 39.54 -
2回目 31.96 -7.58
3回目 7.58 -24.38
4回目 6.64 -0.94
5回目 6.66 0.02


結果をみてみると、キャッシュサイズを100MBや200MBにしたとき、3回目の実行時に約25秒も処理時間が短縮されており、他に比べて大きな効果が出ていることがわかります。しかしもともとの時間が大きいので、パフォーマンスとしてはけっしてよいとはいえません。2回目以降の相対的な時間の差異ではなく、絶対的な処理時間をみると、明らかにデフォルト設定が優位であることが分かります。このことから、『MaxBufferSizeの設定値によって微妙にパフォーマンスが変わることは確かであるが、大きければ大きいほどよいということはなく、デフォルト値のままが最適のようである』と結論付けてよさそうです。パソコンの総メモリ容量などに応じてこのレジストリ値を変えてパフォーマンスを調整することはできるが、Jetデータベースエンジンが自動的にしてくれる(であろう)設定はかなり最適化されているものであり、わざわざこれを変更するほどのことはないといえるでしょう。


なお、今回のテストで、次のような現象を確認することができました。
  • Jetデータベースエンジンの内部キャッシュのサイズをあまりに大きくすると、処理途中で「メモリ不足」のメッセージが出て、処理の続行が不可能となる

  • 少ないレコードのテーブルの場合にはかなり処理が高速に行なわれるが、レコード数を増やしていくと、ある時点からハードディスクへのアクセスが頻繁に発生するようになり、処理速度が落ちる

これらは、おそらくWindows自体が持つディスクキャッシュなどの影響ではないかと思われます。Jetデータベースエンジンの内部キャッシュもさることながら、パソコンにそれなりのメモリを搭載することによって、あるいは高速なハードディスクを使うことによって、また異なるパフォーマンスが得られそうです。その一方で、総メモリ容量を考慮せず、レジストリのMaxBufferSizeだけをいじることは、やはり危険があるといえるかもしれません。
| Index | Prev | Next |

 

Copyright © T'sWare All rights reserved