- 締切済み
C#のデータベースプログラムの効率について
Visual C# 2013 Expressを独学で学んでいます。初心者です。 現在Oracleのデータベースから、SQL文でデータを取得して 処理するプログラムを作っています。 取得したデータはDataTableオブジェクトに入れて、 行列をfor文で検索するようにして作っています。 そこで疑問なのですが、プラグラムのはじめにSELECT文で 複数の項目を一気に取得してDataTableを使いまわす場合と、 そのつど必要な項目だけ小分けに取得する場合どちらが 早い(効率のよい)処理なのでしょうか? 例1)一気に取得する場合 5000行×10列×処理10回:for文は500000回、データベースの取得は1回のみ 例2)小分けに取得する場合 5000行× 2列×処理10回: for文は100000回、データベースの取得は10回必要 例1のほうがサーバの負担が軽くて良いと思っているのですが、どうなのでしょうか? すごくわかりづらくて申し訳ないですが、どなたか教えてください。 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- kmee
- ベストアンサー率55% (1857/3366)
5000行× 2列×処理1回: for文はなし、データベースの取得は1回 にしてしまう、ということです。 具体的な内容がわからないので、具体的なやり方は説明できませんが 例えば 「元のTableAのA1 と、 TableBのB2=A2となっている行のB3列の合計値と比較して、A1>B3の総計の項目を抽出」 とか言ったこともSQLだけでできるのです。 元々大量のデータを連携させて効率よく使うことを考えてあるのがデータベースシステムです。 大量のデータ処理はそっちにまかせて、DataTableには結果を受け取るだけ、というようにした方が効率はいいです。 SQLの解説書等を読むと テーブルを集合と考えて、集合の和や積で必要な集合を求めるようにする。 繰り返しだのと言った手続き型プログラミングの手法は忘れる。 などと書いてあることがあります。 完全にはできなくても、「Forで比較しなければできない」と思考停止するのだけは、止めた方がよいでしょう。
- kmee
- ベストアンサー率55% (1857/3366)
効率がいいのは、SQLを工夫して、小分けにしつつ取得も1回にすることでしょう。 検索はDBの基本機能と言えるでしょう。 よほど無茶苦茶な条件でなければ、SQLのWHERE等でできるのでは? forも減らせるはずです。
- drum_KT
- ベストアンサー率43% (1108/2554)
データベースを使用するのが「そのプログラムが1本のみ」であればどちらでもいいですが、通常、データベースというのは、複数の利用者が並行して読み書きを行うものなので、例1)のようなデータの取り方をしてしまうと、それ以降誰か別の人(プログラム)がデータベースに対して行った変更との整合性が取れなくなります。 その意味では、例2)でもまだ不十分で、実際にはトランザクションというものを意識した処理を考える必要があります。例えば、以下のような流れです。 トランザクション開始宣言 - Select - 何らかの処理 - Update - トランザクションのコミット処理 このトランザクションの開始から終了までの間、簡単に言うと、Selectした範囲はロックがかかって他の人がUpdateできなくなります。そうすることでデータ更新の整合性を保つのがデータベースサーバの最も重要な機能ですが、当然、ロックが長時間かかっていると他の人が処理待ちになる時間が長くなり全体の処理効率が下がりますので、処理に必要な最小単位でロックして、できるだけ早く処理を終わらせて解放してあげる必要があります。
お礼
回答ありがとうございます。 おっしゃるとおり色々なプログラムを、多人数で利用する予定です。 トランザクションは他のプログラムで使ったことがありますが、ロック時間のことまで考えて作ってはおらず、今回とても勉強になりました。これからはできるだけ最小単位でロックされるようなプログラムを作りたいと思います。 ありがとうございました。
補足
回答ありがとうございます。 小分けにしつつ、取得も1回にするとはどうしうことでしょうか?SELECT文は1回で、他(UPDATEやDELETEなど)は小分けにという意味でしょうか? 今回作りたいプログラムは複数の列を取得して、取得したデータを他のデータと比較するようなプログラムなのです。ですのでWHEREで絞らず、for文で列の全数比較する必要があります。