SQLの速度改善についての参考資料。詳しくは記載したURLへアクセス。
要約すると…DataAdapterで自動生成されたSQL(更新系・追加・削除)を
そのまま使用すると、連続処理の場合は特に速度が低下する仕様とのことです。
DataAdapterを別の方法(ストアド等)に書き換えるのがベストですが、
書き換えが難しい場合、手で修正したSQLに変更する方法でも効果は
高いことが分りました。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=6851&forum=7
VB.NET- 更新処理時SQLServerタイムアウト
VB.NETにてSQLServer2000のテーブル更新プログラムを作成しています。
作成しているのは1000万件ほどの件数があるKYKINFOテーブルに対して、
別のテーブル(dbUtmp表)の値をJIGYOCD,KYKNOをキーとして更新するプログラムです。
と全項目が最初にSELECTした値と等しいかAND条件に入れているようなのです(--;
このテーブルが項目数が120個程度あるのですが、それらがすべてWHERE句に
入ってしまっています。
こういった仕様なのでしょうか。。。プライマリキーのみで更新できるようにする
よい手がありましたらご教授ください。
やはりできないんですね。とりあえずCommandBuilderで作成したSQL文の
WHERE句以降をロジックで置き換えることで対応しました。
これからはCommandBuilderはできるだけ使用しないようにします。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=18290&forum=7&start=16
コマンドビルダはあまり使わないほうが無難でしょうか。
まじめに自分でSQL文を生成したほうが安全ですかね。
性能を考慮されるのでしたら、DataAdapterのUpdateメソッドで使用する
INSERT, UPDATE, DELETE用のSQL文をストアドプロシージャに自前で用意
すべきです。
http://www.microsoft.com/japan/msdn/thisweek/meikaiADONET/meikaiADONET1.aspx
SqlCommandBuilder クラスを利用すると、更新系のSQL 文が自動生成される。
Visual Studio .NET のデータアダプタ構成ウィザードにおいても同様の
SQL 文が生成される。ここで自動生成される SQL 文には、最初に Fill メソッドで
読み込んだ段階のすべての列の値が Where 句の条件として含まれる。これによって
楽観的 (オプティミスティック) 同時実行制御を機能的に実現している。
DataAdapterのFill() メソッドによって最初にDataSet 内にデータを格納した後に、
DB の元のデータがほかで更新された場合、読み込んだ段階の項目値を
Where 句に持つ Update 文や Delete 文の更新件数は 0 件となる。この状態は、
DataAdapter の Update() メソッドの実行時の DBConcurrencyException が発生する
ことで検出できる。したがって、ほかで更新された場合の対処はこの例外を
キャッチすることでハンドリング可能である。なお、この自動生成された更新系 SQL 文
をそのまま使用するかどうかは開発者の自由である。たとえば DBMS 側で
タイムスタンプ列やバージョン番号列を実装し (タイムスタンプの更新やバージョン番号
の更新はトリガとしてあらかじめ実装)、それを Where 句内で主キー列と共に
比較対象とするといった方法もある。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=33506&forum=7&9
CommandBuilderはパフォーマンスを考えるにあまりオススメしません。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpguide/html/cpconUsingStoredProceduresWithCommand.asp
コマンドによるストアド プロシージャの使用
http://www.agtech.co.jp/html/v9manuals/adonet/adonet-09-2.html
CommandBuilder オブジェクトの使用
CommandBuilder オブジェクトは SQL ステートメントを生成するには便利だと
思われがちです。しかし、これを使用するとパフォーマンスに悪影響を及ぼす
恐れがあります。同時処理の制限が原因で、CommandBuilder オブジェクトは
効率のよいSQL ステートメントを生成することができません。
たとえば、次の SQL ステートメントは、Command Builder で作成されたものです。
エンドユーザーが作成した Update ステートメントと Delete ステートメントの方が、
Command Builder が生成するステートメントより効率がよい場合もよくあります。
もう 1 つの問題は、CommandBuilder オブジェクトの設計にあります。
CommandBuilder オブジェクトは常に DataAdapter オブジェクトと関連付けられ、
DataAdapter オブジェクトが生成する RowUpdating イベントと
RowUpdated イベントのリスナーとして CommandBuilder オブジェクト自体を
登録します。したがって、行を更新するたびに、この 2 つのイベントが処理
されなければなりません。