#28 | 明細データテーブルの集計を考える | |||||||||||||||||||||||||||||||||||||||||||||||
売上伝票テーブルと売上明細テーブル、入出庫伝票テーブルと入出庫明細テーブルなどのように、伝票ごとの見出しにあたる部分のデータと、その中の明細データとを分けてテーブル設計することはよくあると思います。そしてそれらは、通常、リレーションシップやクエリーによって、一対多の関係で結合されて利用されます。例えば、次の「入出庫伝票」テーブルと「入出庫明細」テーブルの例では、入出庫伝票テーブルには、1伝票1レコードで、伝票ごとのIDとその日付だけが保存されています。また、入出庫明細テーブルには、商品別の発注数や入出庫数が伝票1枚に対して複数レコード保存されています。両者は「伝票ID」フィールドで結合され、一対多の関係を持っています。 このような関係を持った2つのテーブルを結合し、しかも、明細データテーブル側のデータを集計するようなクエリーを作る場合、一般的には、通常の選択クエリーを構成したあと、グループ化や合計などの集計クエリーの設定をしていくと思います。しかし、このような機能を持ったクエリーの作り方には、他にもいくつかの方法があります。ここでは、どのような方法があるかピックアップしてみるとともに、それらのうち、どの方法で集計を行うのがもっとも処理が高速か、比較検討してみたいと思います。
これらはいずれも最終的に得られるデータは同じものですが、これらのテスト用クエリーを作る段階では、2〜4は作成が面倒そうという印象がきっとあるでしょう。しかし、もしパフォーマンスに大きな違いがあるのであれば、アプリケーションとしては、多少の手間は犠牲にしても、実用面でメリットの高いものを選択した方がよい場合もあります。 Dim dbs As Database Dim rst As Recordset Dim qdf As QueryDef Dim strQryName As String Dim iintLoop As Integer Set dbs = CurrentDb ts_Watch "テスト開始", True strQryName = "単独クエリー集計": GoSub QryTest strQryName = "複数クエリー集計": GoSub QryTest strQryName = "サブクエリー集計": GoSub QryTest strQryName = "DSum集計": GoSub QryTest Exit Sub QryTest: For iintLoop = 1 To 10 Set qdf = dbs.QueryDefs(strQryName) Set rst = qdf.OpenRecordset() '2つ目のテストでは次の1行を追加してみます 'rst.MoveLast rst.Close qdf.Close Next iintLoop ts_Watch strQryName Return テスト結果は次のようになりました。 この結果から、気づいた点を列挙してみます。
今回のテストに使ったテーブルでは、「入出庫伝票」には4400件のレコード、「入出庫明細」には5000件のレコードが保存されています。平均すると、1伝票あたり1.14件の明細データしかないことになります。一口に一対多とはいっても、1伝票に100件の明細データがある場合もあれば、ほとんど1伝票1明細の場合もあるでしょう。また、トータルのレコード数自体も、数百の場合から数万の場合まであるわけで、そのようにいろいろ状況が変わったとき、この結果がどれだけ変わるかは何ともいえません。しかしもし、処理時間でネックとなる一対多の関係を持ったテーブル間の集計クエリーがあれば、クエリーの作成方法を変えることによって何らかの改善が見られるか、比較・確認してみるのもよいでしょう。 個人的には、集計クエリーの新規作成の容易さ、メンテナンス性などを考えると、やはり一般的な1番目の方法を中心に使うことになると思います。しかしもし、非常に大量のレコードを扱うような処理で、時間がかかって仕方ないと思われるような場面に遭遇したら、上記の他の方法を試してみようと思います。 また、これまでは、大量のレコードを持ったテーブルに対してはその使用を控えていた「定義域集計関数」も、なかなか使えそうであることが分かったので、今後は積極的に使ってみようと思います。特に、今回例として作成したクエリーデザインを見ても分かるように、サブクエリーを使わざるを得ない場面になったとき、そのほとんどは定義域集計関数で代替が利きそうです。総まとめとしては、「状況によって1と4の方法を使い分ける」ということになるのではないでしょうか。 |
||||||||||||||||||||||||||||||||||||||||||||||||
|
Copyright © T'sWare All rights reserved |