- 結論
- OpenRecordset メソッドでのレコードセットタイプの選択はAccessに任せよう!
ただし前方向のみのレコード移動しかないクエリーに対する処理では ForwardOnly を使う価値あり。
Access Labo の#01から#03では OpenRecordset メソッドのパラメータをいくつか比較してみましたが、 OpenRecordset
メソッドにはもう一つ重要なパラメータがあります。レコードセットの"タイプ"です。重要でありながらこれがこれが実験の後回しになってしまったのには訳があります。レコードセットのタイプは、OpenRecordset
メソッドのソースがテーブルである場合には自動的に "Table" タイプに、またクエリーの場合には "Dynaset"
タイプになります。つまり既定値として最適なタイプを自動的に選択してくれるわけです。そのため、特にその違いを気にしていなかったのです。しかし、その既定値はいかなる場合にも最適なのか、またこれ以外のタイプ、つまり
"ShapShot" や "ForwardOnly" では処理時間にどのような違いがあるのか、やはり試してみるべきと考え、ここで取り上げてみました。
テストの内容としては、あるテーブル、およびそのテーブルのすべてのフィールドとレコードを単純に取り出すだけのクエリーに対して、5万件のレコード追加とその全レコードの読み込み、全レコードの更新、さらに全レコードの削除をVBAを使って行うものです。コードは次のようなものです。
Dim dbs As Database
Dim rst As Recordset
Dim strName As String
Dim ilngLoop As Long
Const cRecMax As Long = 50000
Set dbs = CurrentDb
ts_Watch "テスト開始", True
Set rst = dbs.OpenRecordset("tblTest", dbOpenTable)
GoSub AddSub
ts_Watch "テスト1"
'レコード移動の時間を測定しないようにレコードセットをオープンし直します。
Set rst = dbs.OpenRecordset("tblTest", dbOpenTable)
GoSub SelectSub
ts_Watch "テスト2"
Set rst = dbs.OpenRecordset("tblTest", dbOpenTable)
GoSub EditSub
ts_Watch "テスト3"
Set rst = dbs.OpenRecordset("tblTest", dbOpenTable)
GoSub DeleteSub
ts_Watch "テスト4"
'以下同様に dbOpenDynaset、Snapshot、ForwardOnly についてテストします。
'ただし、SnapshotとForwardOnlyでは追加や更新・削除はできないので、時間測定はしません。
Set rst = dbs.OpenRecordset("qselTest", dbOpenDynaset)
'以下同様にテーブルの場合と同じパターンでクエリーに対してテストします。
Exit Sub
AddSub:
With rst
For ilngLoop = 1 To cRecMax
.AddNew
!Name = "ABCDE"
.Update
Next ilngLoop
.Close
End With
Return
SelectSub:
With rst
For ilngLoop = 1 To cRecMax
strName = !Name
.MoveNext
Next ilngLoop
.Close
End With
Return
EditSub:
With rst
For ilngLoop = 1 To cRecMax
.Edit
!Name = "12345"
.Update
.MoveNext
Next ilngLoop
.Close
End With
Return
DeleteSub:
With rst
For ilngLoop = 1 To cRecMax
.Delete
.MoveNext
Next ilngLoop
.Close
End With
Return
そして、テスト結果はつぎのようなものになりました。なお、ここでの * マークは組み合わせ不可を表しています。また時間の単位は"秒"です。
ソース |
タイプ |
追加 |
選択 |
更新 |
削除 |
テーブル |
Table(既定) |
32.0 |
4.4 |
36.6 |
15.7 |
Dynaset |
49.9 |
7.0 |
60.2 |
38.2 |
ShapShot |
|
7.4 |
|
|
ForwardOnly |
|
4.7 |
|
|
クエリー |
Table(既定) |
|
|
|
|
Dynaset |
50.8 |
6.9 |
58.9 |
37.1 |
ShapShot |
|
7.4 |
|
|
ForwardOnly |
|
4.7 |
|
|
テスト結果から、Accessが決めてくれる既定のタイプは全般的には最適なものと再確認できたのではないでしょうか?
ちょっと意外だったのは ShapShot タイプがそれほど速くないということです。ShapShot タイプでは、複数のユーザーが同時にアクセスするような環境で、レコードセットを読み込んだ後に他のユーザーがそれらのレコードを更新しても、自分がすでに読み込んだレコードには反映されません。つまり他のユーザーによるレコード更新を監視するための何らかの内部処理が必要ないわけですから、時間的な差が出てもいいと思われるのですが、このメリットはやはり実際にLAN接続されているようなマルチユーザー環境でないと無いのでしょうか?(ちなみにこのテストは完全にスタンドアロンで行っています)
もう一つ結果から分かる特徴的なことは、クエリーに対して ForwardOnly を使用すると時間的メリットが出てくるという点です。もちろん、それぞれのタイプによってレコードに対する操作に制限事項がありますので、それについてはその制限を優先して考える必要があります。例えばブックマークなどを使って前後にレコード移動するような処理ではこの
ForwardOnly は使えないわけですから、あくまでも「前方向のみのレコード移動ではメリットがある。」ということになります。
|