定義域集計関数(D~関数)のパフォーマンスについて

このQ&Aのポイント
  • 定義域集計関数(DAv、DCount、DFirst、DLast、DMax、DMin、Dsum、DLookupなど)を使用すると、対象とするテーブルの全レコードをクライアントに持ってきてから計算や検索を行ないます。
  • そのため、基となるテーブルのデータ量が多い場合は、ネットワーク上のトラフィックが増えて、結果が表示されるまでのパフォーマンスが悪くなります。
  • レスポンスの向上を図るには定義域関数をストアド等に置き換える必要があります。
回答を見る
  • ベストアンサー

定義域集計関数(D~関数)

AccessのVBA関連ですが、とある書籍に下記のような記述がありました、 真偽の程はいかがでしょうか? (書籍のレベルはSQLの入門レベルです、MDB→ADPで効率アップする手順書の様な本です) 表題「SQL Server noパフォーマンスを引き出せない関数」 内容「定義域集計関数(DAv、DCount、DFirst、DLast、DMax、DMin、Dsum、DLookupなど)を使用すると、 対象とするテーブルの全レコードをクライアントに持ってきてから計算や検索を行ないます。 そのため、基となるテーブルのデータ量が多い場合は、ネットワーク上のトラフィックが増えて、 結果が表示されるまでのパフォーマーンスが悪くなります。 この場合も、SQL Serverに計算をさせるようにするか、値を取得してからコントロールに 代入するようにします。」・・・(原文のまま) 要は「レスポンスの向上を図るには定義域関数をストアド等に置き換える必要がある」と 解釈したのですが、実際はどうなんでしょうか?

  • SEsyo
  • お礼率78% (64/82)

質問者が選んだベストアンサー

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

あくまでも(経験に基づく)私見ですが、書かれている内容は正しいです。それらの関数はSQL Serverで解釈できるようにOLEが変換できないので、ACCESSのあるクライアント側までデータを引っ張ってこないと判断できないです。必然的にトラフィックは増えます。 同じようなことが、リンクテーブルとローカルテーブルのJOINや、クエリ内でテーブルを参照するタイプのACCESSユーザ定義関数を使用するケースなどでもいえます。 Accessももともと閉じたデータベースとして使えるものですし、便利な機能がたくさんありますが、ACCESS外のDBMSで管理するデータを扱う場合はパフォーマンスを考えればデータのある側で処理するに越したことはないでしょう。 ネットワークのトラフィックを減らすためには、書き換える方法は別にストアドプロシージャでなくて通常のクエリでもかまわないので、少なくともデータ抽出に関しては純粋にSQL Serverが解釈できるSQL文を投げて、必要十分な結果だけを受け取るようにすることでしょう。 (具体的にACCESSがどんなSQLをSQL Serverにリクエストしているかを確認するためにSQL Serverプロファイラを活用することをお勧めします) ちなみに突き詰めていくと、すべてのDBアクセスをパラメータ付のストアドプロシージャだけで行うという方向性になると思います。Webアプリなどはこういうアプローチも多いです。

SEsyo
質問者

お礼

すいません今頃、回答が来ました。 ------------------------------------------------------------------------------ ご指摘いただいたとおり 「定義域集計関数は対象とするテーブルの全レコードをクライアントにもってきてか ら計算や検索を行ないます・・・トラフィックが増えて、結果が表示されるまでのパ フォーマーンスが悪くなります。」 のくだりは間違っておりました。 誠に申し訳ございませんでした。 記述根拠の出所は大変申し訳ございませんが、諸事情がありお答えできませんが 確認の仕方が足りなくて誤った情報を記載したことを申し訳なく思います。 ------------------------------------------------------------------------------ もう一日までば良かったです、だけど・・・あり得ないことが、あり得るんですね・・・

SEsyo
質問者

補足

回答ありがとうございます。 私も本が間違っているとは思えないのですが、実践経験者はD関数でも早いから問題ないよ、ってな感じです。 今朝、100万件のテストデータを作成し試してみました。 キーは1~999999として項目に0と1をセットし1の数をカウントしました。 キーと項目以外に備考と言う名称に「aaaaaaaa」といれてあります。(レコード長を伸ばすため) インデックスは付けてありません。 Msgbox DCount("キー","TEST") Msgbox DCount("キー","TEST","項目=1") を実行したら両方とも0.5秒ほどでした。(10万件も同じ時間) どうも、サーバー側で作業をしているように感じるのでですが、どうなんでしょうか? 私の検証の仕方に問題があるのでしょうか?

関連するQ&A

  • ACCESS VBAの定義域集計関数の条件設定について

    ACCESSのVBAで定義域集計関数のDsum関数を使用しています。 Dsum関数は 結果=Dsum(フィールド名、テーブル名やクエリ名[、条件]) で、条件については、SQL分のWHERE句ののWHREを除いた部分を記述すると解説されています。 そこで月別経費一覧表のクエリーから経費月を2004.4月、5月、6月の累計を出すべく下記の様な式を作って見ました。 累計経費実績 = DSum("[金額]", "qry月別経費一覧", "経費月 IN('2004.04','2004.5','2004.6')") 実行してみると、条件であるIN句の中のはじめの条件'2004.4'月の[金額]の合計だけが計算されます。 順番を入れ替えて、'2004.5'を先頭にすると5月分の[金額]の合計のみが計算されました。 本来、3ヶ月分の[金額]が合計されて欲しいわけですがどこに不具合があるか解りません。 いろいろと調べてみましたが原因がわかりません。 ネット等でも探しましたが見つけることが出来ませんでした。 どなたかおわかりの方お教えください。 使用PCはWINDOWS XP/ACCESS2000です。 よろしくお願いします。

  • PostgreSQL(8.4.2)のユーザ定義関数(ストアドプロシージ

    PostgreSQL(8.4.2)のユーザ定義関数(ストアドプロシージャ)を、 ODBC経由でVisualStudio2005から利用したいのですが、 サーバーエクスプローラーからユーザ定義関数を参照することが出来なくて悩んでいます。 ユーザ定義関数はpgAdminIIIで作成しました。 cse(Common SQL Environment)などのフリーのツールからは問題なく参照できます。 VisualStudioにユーザ定義関数として認識させるための何かおまじない的な物が必要なのでしょうか。 それともPostgreSQLとVisualStudioとの相性が悪いのでしょうか。 なおユーザ定義関数以外であるテーブルやビューは、 サーバーエクスプローラーから参照できます。

  • Access2002 Insert関数が未定義関数となり、エラー

    XP Access2002です。 ランキング形式のテーブルから、クエリを作成しています。 クエリでの表示は A1 となっているのですが、それにハイフン「-」を入れて、A-1としたいです。 「A1」は、テーブル名:「ランク」内のフィールド名:「順位」 SQLビューで insert(ランク!順位,2,0,'-') AS ランキング としたのですが、結果は、未定義関数と出てしまいます。 InsertをReplaceに変更したら、今度はアラーとは出ませんが、表示画面では、エラー表示になってしまいます。 構文が違うのでしょうか? SQLを使っていて、『未定義』とアラートが出たのは初めてですので、戸惑っています。

  • SELECT文でLEFT関数を使うと未定義関数ですと言われる

    VBソース上では SELECT LEFT(~~~,4) AS 項目 FROM テーブル と SELECT文で書いてもエラーにならずオープンできるみたいなのですが そのSQL文をACCESS2000上で動かすと 未定義関数LEFTがあると言われます どなたか分かる方至急お願いします!!!

  • ACCESSのクエリでDlookup関数・戻り値の属性は

    ACCESSのクエリの中で、抽出したい項目を式で定義しているのですが、Dlookup関数を使っています。 そのとき、数値項目だと思っていたのですが、文字として値が返ってきているようです。(数字が左詰めになっているので) Dlookup関数の戻り値は、このような使い方をした場合、文字として返ってくるのでしょうか。 (Nullというのが返ってきている場合もありました) クエリ上で使っている式は、このようなものです。 前月戸建契約数: DLookUp("契約数","テーブル名", "担当者名='" & [担当者名] & "' And 月次='" & [前月] & "'") [担当者名]は元になるテーブルにあり、[前月]はクエリ上で、(テーブル上の)[月次]-1で式として定義しています。 よろしくお願いします。

  • SQL2000でのユーザ定義関数作成に関する質問です。

    開発環境はvb6, SQLサーバ2000です。 下記のようなテーブルから実行結果に記入してある結果を得れるようなユーザ定義関数をおしえていただきたいです。 分類マスタ(KEY=分類CD) -------------------------------------------- 分類CD  |分類名  -------------------------------------------- 1    |魚類   | -------------------------------------------- 2    |野菜   | -------------------------------------------- 3    |牛肉   | -------------------------------------------- 4    |豚肉   | -------------------------------------------- 親テーブル(KEY=会員CD) -------------------------------------------- 会員CD  |会員名 |出身地 | -------------------------------------------- 1    |田中  |大阪  | -------------------------------------------- 2    |佐藤  |東京  | -------------------------------------------- 3    |中井  |鹿児島 | -------------------------------------------- 子テーブル(KEY=会員CD, 枝番) -------------------------------------------- 会員CD  |枝番  |分類CD  |処理日 -------------------------------------------- 1    |1   |1    |1/1 -------------------------------------------- 1    |2   |2    |1/2 -------------------------------------------- 1    |3   |2    |1/3 -------------------------------------------- 1    |4   |4    |1/4 -------------------------------------------- 1    |5   |2    |1/5 -------------------------------------------- 1    |6   |3    |1/6 -------------------------------------------- 1    |7   |4    |1/7 -------------------------------------------- 2    |1   |1    |1/1 -------------------------------------------- 2    |2   |2    |1/2 -------------------------------------------- 2    |3   |1    |1/3 -------------------------------------------- 2    |4   |1    |1/4 -------------------------------------------- 2    |5   |4    |1/5 -------------------------------------------- 2    |6   |1    |1/6 -------------------------------------------- 2    |7   |4    |1/7 -------------------------------------------- 3    |1   |3    |1/1 -------------------------------------------- 3    |2   |3    |1/2 -------------------------------------------- 3    |3   |3    |1/3 -------------------------------------------- 3    |4   |4    |1/4 -------------------------------------------- 3    |5   |4    |1/5 -------------------------------------------- 3    |6   |4    |1/6 -------------------------------------------- 3    |7   |2    |1/7 -------------------------------------------- これら三つのテーブルを連結し、尚且つユーザ定義関数を使用し、下記のような結果を得たいです。 -------------------------------------------------- 会員CD |会員名 |魚類 |野菜 |牛肉 |豚肉 | -------------------------------------------------- 1    |田中  |1   |3   |1   |2   | -------------------------------------------------- 2    |佐藤  |4   |1   |0   |2   | -------------------------------------------------- 3    |中井  |0   |1   |3   |3   | -------------------------------------------------- 要は、親テーブルの会員をベースに、子テーブルに登録されている情報を分類CD単位で集計し、横に展開し、1レコードで保持したいと思っています。 わかりにくい文とは思いますが、どうか教えていただけますようよろしくお願い致します。

  • ユーザー定義関数の意味

    下記のユーザー定義関数の意味を自分なりに解釈しました。 下記の意味で合っていますか? // $dbと$user_idを受け取ったget_user関数は、$dbと$sqlを受け取ったユーザーの情報を取り出す function get_user($db, $user_id){ // データベースに接続してusersテーブルからuser_idが$user_idに一致するuser_id、name、password、typeを1行だけ表示する $sql = " SELECT user_id, name, password, type FROM users WHERE user_id = {$user_id} LIMIT 1 "; return fetch_query($db, $sql); } // $dbを受け取ったget_login_user関数は、変数dbと変数login_user_idを受け取ったget_user関数を返す function get_login_user($db){ // 変数login_user_idをセッションのユーザーIDと定義する $login_user_id = get_session('user_id'); return get_user($db, $login_user_id); }

    • ベストアンサー
    • PHP
  • VBAでユーザー定義関数作りにチャレンジしてます。

    DATEDIF関数をなんとかユーザー定義関数に組み込んでみようと思い、VBAをはじめてみました。 標準モジュールでFunctionを使って書くところまでは何とかたどり着いたのですが、 DATEDIF自体の計算についてどうやって場合わけしていったらいいのか悩み始めてしまいました。 DATEDIF(開始日,終了日,単位)とした場合、 単位="D"もしくは"d"ならば、(開始日-終了日)/ 1 と、適当ではありながらも考えてみました。 そこからが問題で、月数、年数を数えるときに日付の違う月数をどうやって数えるのか、とか、うるう年の計算をどうしたらよいのかとか。。。 単にシリアル値を取り出して割るだけじゃだめですよね? 検索でユーザー定義関数についても、DATEDIF関数自体に関してもしてみたのですが、どうしても理解に苦しんでいます。 直接の答えでなくてもいいので、関連サイトや関連書籍でいいものがあったら教えてください。 本当は本は人に言われて買うものではないと思っているのですが、自分の踏み込んだことのない分野なのでちょっと手のつけようがなくて困っています。。。 どうかお願いします。

  • aspでユーザー定義の構造体を作成したいのですが?

    sql2000serverにデータを書き込みたいのですが、テーブル定義がbinaryを一部含んでいるので、構造体をと考えました。 structure?、Type? でそのあとは? ほかに方法があれば、ご教授願えませんでしょうか? よろしくお願いします。

  • ユーザー定義関数

    自サイトのアクセス解析をしようと SERVER変数を取得してログを解析しようとPHPで組んでみたのですが、 いまいちユーザー定義関数の上手?な使い方がわかりません。 アドバイスを頂けると幸いに思います。 データはcsv(すみませんSQL使えません)ファイルに1アクセス1行 日付,時間,キャリア等々 と記述しています。 ドコモをカウントする場合 function doco( $Key){ $handle = fopen( "LogFile", "r"); $count= 0; while (($data = fgetcsv($handle)) !== FALSE) {  if( mb_eregi( $Key, $data[2])){ $count++; } } echo $count; fclose($handle); } doco( "DoCoMo"); となり、さらに時間別にドコモで0時に来訪したのは何人? といった場合 ifの中にさらに時間の判別のifを記述し 引数の部分を増やしdoco( 引数1,引数2)見たいな感じにしますが そうではなく、 ドコモだけの人数を取り出したい場合も ドコモから12時の人数だけを取り出したい場合も 同じユーザー定義関数を使う方法はありますか? 宜しくお願いします。

    • 締切済み
    • PHP