C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: レコード追加更新のループ


(過去ログ 100 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■59786 / inTopicNo.1)  レコード追加更新のループ
  
□投稿者/ 田村 (1回)-(2011/06/07(Tue) 11:29:41)

分類:[C#] 

C#2008、SQLServer2008

CSV読み込みで、レコードの追加・更新をループで100件〜1000件程度行うのですが、
キーのレコードが存在したら更新、存在しなかったら追加という処理で、
毎回レコードを参照しに行っていて、DataTableを毎度newしてインスタンスを作っているのですが、
このせいか80件目くらいから処理がだんだん遅くなってきます。
この処理の速度をなるべく落とさずに行うにはどんな方法があるでしょうか?

引用返信 編集キー/
■59788 / inTopicNo.2)  Re[1]: レコード追加更新のループ
□投稿者/ shu (762回)-(2011/06/07(Tue) 11:44:23)
No59786 (田村 さん) に返信
> C#2008、SQLServer2008
>
> CSV読み込みで、レコードの追加・更新をループで100件〜1000件程度行うのですが、
> キーのレコードが存在したら更新、存在しなかったら追加という処理で、
> 毎回レコードを参照しに行っていて、DataTableを毎度newしてインスタンスを作っているのですが、
> このせいか80件目くらいから処理がだんだん遅くなってきます。
> この処理の速度をなるべく落とさずに行うにはどんな方法があるでしょうか?

編集テーブルの総件数がそれほど多くないのであれば
(1)トランザクション開始
(2)SqlDataAdapterを作り
(3)FillでDataTableに登録済みデータの取得
(4)DataTableへの追加、更新を行う(CSVの行数分)
(5)SqlDataAdapter.Updateを実行
(6)トランザクションをコミット

というやり方もあります。最速ではありませんが、改善されると思います。
引用返信 編集キー/
■59790 / inTopicNo.3)  Re[1]: レコード追加更新のループ
□投稿者/ Mira (49回)-(2011/06/07(Tue) 12:11:04)
データーベース側がキーの重複をチェックできるのであれば

データーあるなし関係なしにInsertを実行しエラーが出た時だけUpdateを実行すれば
かなり早くなります
引用返信 編集キー/
■59800 / inTopicNo.4)  Re[1]: レコード追加更新のループ
□投稿者/ 魔界の仮面弁士 (2200回)-(2011/06/07(Tue) 14:32:45)
No59786 (田村 さん) に返信
> この処理の速度をなるべく落とさずに行うにはどんな方法があるでしょうか?
件数が少ないので、SSIS でもループ処理でも良いとは思いますが、DELETE or INSERT 処理については
「MERGE ステートメント」を使った方が効率が良い気がします。
引用返信 編集キー/
■59802 / inTopicNo.5)  Re[2]: レコード追加更新のループ
□投稿者/ 田村 (2回)-(2011/06/07(Tue) 16:38:58)
Updateメソッド方式もあまり変わらなかったです。
MERGEはSQLだったんですね。MERGE文知らなかったです。
これも試してみます。
ありがとうございました。
引用返信 編集キー/
■59817 / inTopicNo.6)  Re[2]: レコード追加更新のループ
□投稿者/ 魔界の仮面弁士 (2204回)-(2011/06/07(Tue) 20:20:24)
No59802 (田村 さん) に返信
> Updateメソッド方式もあまり変わらなかったです。
もしかして、DataAdapter(TableAdapter) の Update メソッドを使ったのでしょうか?
その時に、引数に SELECT した DataTable を渡してはいませんか?

追記のみの作業において DataTable を経由させるのは、効率が悪いです。


■No59790 (Mira さん) に返信
> データーあるなし関係なしにInsertを実行しエラーが出た時だけUpdateを実行すれば

逆にした方が良いと思いますよ。つまり、UPDATE → INSERT の順です。

たとえば、
  CREATE TABLE TEST (
    COL1 INT PRIMARY KEY,
    COL2 VARCHAR(10)
  )
だと仮定して、ここに 「100, 'TEST'」という行を登録する場合、

(1)「UPDATE TEST SET COL2 = 'TEST' WHERE COL1 = 100」を実行する。
(2) 影響を受けた行数が 1 件だったら更新完了。0 件だったら次の(3)を実行。
(3)「INSERT INTO TEST (COL1, COL2) VALUES (100, 'TEST')」を実行する。

という流れにするわけです。これなら重複登録のエラーを気にする必要もありません。


なお、手順(2) の影響を受けた行数は、SqlCommand.ExecuteNonQuery メソッドの戻り値で得られます。
(TableAdapter の Insert/Update メソッドの戻り値でも可)

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -