#24 | フィルタのかかったレコードセットをどう開くか? | |||||||||||
Accessをはじめとする「データベース」というジャンルに属するソフトの最も得意とするところが、レコードの抽出や並べ替え、テーブル結合といったSQLによるデータ操作です。Accessの場合、これをGUIで簡単に操作できるようにしているのが「クエリー」です。SQLという言語を意識せずマウス操作だけでデータベースエンジンに対して発行するSQLを組み立てて、データベースウィンドウに表示されるデータベースの1つのオブジェクトとして保存することができます。この保存済みのクエリーは単独のクエリーオブジェクトとしてデータシートビューのような方法で動作させるだけでなく、フォームやレポートのレコードソース、あるいはコンボボックスなどのコントロールソースとしても利用することができます。またVBAにおいては、そのクエリーからレコードセットを開くことによってあらかじめ抽出・並べ替えなどの操作がなされたレコードを取得することができます。
いずれの方法もテーブルに対して何らかのSQLを発行するのは同じです(FilterプロパティについてはSQLという表現は適切でないかもしれません)。しかし、実行するタイミングあるいはSQLが解釈されるタイミングが微妙に異なるため、パフォーマンスにも何らかの違いが出てくることが想像されます。そこで今回はこの4つの方法についてその実行時間を測定・比較してみることにしました。 Dim dbs As Database Dim rst As DAO.Recordset Dim rstF As DAO.Recordset Dim qdf As QueryDef Dim varDummy As Variant Dim strSQL As String Set dbs = CurrentDb ts_watch "テスト開始", True '【保存済みクエリーを使った方法】 Set rst = dbs.OpenRecordset("テストクエリー") GoSub ReadLoop rst.Close ts_watch "保存済みクエリーで開く" '【保存済みのパラメータクエリーを使った方法】 Set qdf = dbs.QueryDefs("テストパラメータクエリー") With qdf .Parameters("Where Value") = 5 Set rst = .OpenRecordset() GoSub ReadLoop rst.Close .Close End With ts_watch "保存済みパラメータクエリーで開く" '【SQLステートメント自体をVBAから発行する方法】 strSQL = "SELECT * FROM tblTest WHERE Data2 = 5" Set rst = dbs.OpenRecordset(strSQL) GoSub ReadLoop rst.Close ts_watch "SQLステートメントで開く" '【Filterプロパティを使った方法】 Set rstF = dbs.OpenRecordset("tblTest", dbOpenDynaset) rstF.Filter = "Data2 = 5" Set rst = rstF.OpenRecordset() GoSub ReadLoop rst.Close ts_watch "Filterで開く" dbs.Close Exit Sub ReadLoop: With rst Do Until .EOF varDummy = !Data1 varDummy = !Data2 varDummy = !Data3 varDummy = !Data4 .MoveNext Loop End With Return テスト結果は次の通りです。
差異としては1/100秒単位のわずかなものですが、その差を分析してみることにします。まず、最も速かったのが「保存済みクエリーを使った方法」です。クエリーオブジェクトを保存しておくことによってSQLステートメントの解釈にかかる時間が高速化されていることの表れと考えられます。「SQLステートメント自体をVBAから発行する方法」もこれとほぼ同じ時間で処理されています。今回のテストケースは非常に単純なSQLではありますが、少なくともこのようなケースでは保存されたクエリーもVBAからSQLステートメントの文字列を発行するのも同等と考えてよいでしょう。パフォーマンスではなく、使い勝手の面でそれぞれのメリット・デメリットを考えて使い分ければよいようです。
さて、WHERE条件を埋め込んだ保存済みクエリーと同レベルのパフォーマンスを期待していたのに、意外と時間がかかったのが「保存済みのパラメータクエリーを使った方法」です。クエリーオブジェクトの内容を取得し(Set qdf = dbs.QueryDefs〜)、パラメータ値を設定するという処理の分、余分に時間がかかっているのかもしれません。しかしコーディングの面からいえばSQLステートメントのWHERE句を文字列データとして組み立てる必要が要らないという点で、やはり便利な方法ではないでしょうか。 |
||||||||||||
|
Copyright © T'sWare All rights reserved |