- 結論
- Access97では、トランザクションの効果はあるものの、あえて意識してトランザクション処理の"BeginTrans〜CommitTrans"を記述しなくても、それ相応のパフォーマンスが得られる。
Access1.1や2.0のころ、RecordsetオブジェクトのAddNewやEdit、Deleteなどのメソッドを使ってレコード編集を行うと、クエリーを使った同等の処理に比べて非常にパフォーマンスが悪くなるため、そのブロックをBeginTrans〜CommitTransでくくる「トランザクション処理」を常に併用していました。本来トランザクション処理はデータの整合性をとるためのものかもしれませんが、レコードに対する編集結果がメモリ上のキャッシュにバッファリングされるために、驚異的ともいえるパフォーマンスの向上が見られました(それでもクエリーを使った同等の処理と同じくらいでしたが)。そのような経緯もあって、以来使い続けていたのですが、最近のAccessのバージョンでふとそれを記述せずに実行し、後で追加したにも関わらずあまり実行時間が変わらないことに気付きました。そこで今回はあらためてその実行時間を調べてみることにしました。
テストの内容としては、 tblTestSource テーブルに登録されている5万件のレコードを tblTest テーブルに追加、続いてその全レコードを更新し、最後に全レコードを削除します。そして、BeginTrans〜CommitTransを使った場合と使わなかった場合の処理時間を測定・比較します。
テストコードは次のようなものです。
Dim dbs As Database
Dim rstin As Recordset
Dim rst As Recordset
Dim ilngLoop As Long
Const clngRecMax As Long = 10000
ts_watch "測定開始", True
'5万件のレコード追加
Set dbs = CurrentDb
Set rstin = dbs.OpenRecordset("tblTestSource")
Set rst = dbs.OpenRecordset("tblTest")
'DBEngine.Workspaces(0).BeginTrans ---->この有無でテスト
For ilngLoop = 1 To clngRecMax
With rst
.AddNew
----(省略)----
.Update
rstin.MoveNext
End With
Next ilngLoop
'DBEngine.Workspaces(0).CommitTrans ---->この有無でテスト
rstin.Close: rst.Close: dbs.Close
ts_watch "レコード追加"
'5万件のレコード更新
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("tblTest")
'DBEngine.Workspaces(0).BeginTrans ---->この有無でテスト
For ilngLoop = 1 To clngRecMax
With rst
.Edit
----(省略)----
.Update
End With
Next ilngLoop
'DBEngine.Workspaces(0).CommitTrans ---->この有無でテスト
rst.Close: dbs.Close
ts_watch "レコード更新"
'5万件のレコード削除
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("tblTest")
>'DBEngine.Workspaces(0).BeginTrans ---->この有無でテスト
For ilngLoop = 1 To clngRecMax
With rst
.Delete
.MoveNext
End With
Next ilngLoop
'DBEngine.Workspaces(0).CommitTrans ---->この有無でテスト
rst.Close: dbs.Close
ts_watch "レコード削除"
そして、テスト結果はつぎのようなものになりました。なお時間の単位は"秒"です。
|
追加 |
更新 |
削除 |
トランザクションを使わない場合 |
88.8 |
50.6 |
26.0 |
トランザクションを使用した場合 |
87.9 |
48.0 |
25.5 |
ご覧のように、トランザクション処理の効果はAccess97でも確かにありました。この差が大きいか小さいかは考え方にもよると思いますが、以前のバージョンのように"驚異的"とは言えません。これは、Access97の場合はあえて意識して"BeginTrans〜CommitTrans"を記述しなくても、それ相応のパフォーマンスが得られると考えていいかもしれません。Access97(DAO3.5)の場合、AddNewなどのメソッドは従来バージョンのトランザクションのレベルに最適化されているようです。あるいはもしかしたらAccessやDAOが内部的にトランザクションで処理している可能性もあります。
その効果の度合いは減ったとはいえ、Access97のヘルプには「トランザクションによってディスクアクセスの回数が大幅に減少することがある」とあります。例えば、遅いディスクを使っている場合やネットワークドライブに書き込むような場合など、ディスクアクセスの回数が処理時間に大きく影響するような環境では大きな効果があることも考えられます。
|