- - PR -
VB.NET- 更新処理時SQLServerタイムアウト
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-10-13 15:51
VB.NETにてSQLServer2000のテーブル更新プログラムを作成しています。
作成しているのは1000万件ほどの件数があるKYKINFOテーブルに対して、 別のテーブル(dbUtmp表)の値をJIGYOCD,KYKNOをキーとして更新するプログラムです。 KYKINFOのプライマリキーはJIGYOCD,KYKNO です。 以下のようなロジックで実行してみたのですが、最後のUPDATEの部分で時間が かかってしまい、SQLServerのタイムアウト(30秒)になってしまいます。 プライマリキーが更新用インデックスとして使用されればそれほど時間はかから ないはずなのですが、このようなロジックでは使われないのでしょうか? なお、dbUtmp(i)は更新するための元テーブルをビュー化したものです。 まったく違う方法でもかまいませんので解決法をご存知の方、ご教授ください。 Private dvUtmp As DataView Private dadJgyk As New SqlDataAdapter("SELECT * FROM KYKINFO", con) Private dstJgyk As New DataSet() strSQL = "SELECT *" & _ " FROM KYKINFO" & _ " WHERE JIGYOCD=" & dvUtmp(i)("JIGYOCD") & _ " AND KYKNO =" & dvUtmp(i)("KYKNO") dadJgyk.SelectCommand.CommandText = strSQL dstJgyk = New DataSet() dadJgyk.Fill(dstJgyk, "KYKINFO") dtJgyk = dstJgyk.Tables("KYKINFO") drJgyk = dtJgyk.Rows(0) drJgyk.BeginEdit() drJgyk("KYKNAME") = dvUtmp(i)("KYKNAME") drJgyk.EndEdit() dadJgyk.UpdateCommand = cbJgyk.GetUpdateCommand dadJgyk.Update(dstJgyk, "KYKINFO") | ||||||||
|
投稿日時: 2003-10-15 00:56
どんなUPDATE文が投げられているか確認してみてはどうでしょうか。
SQL Serverだと確かプロファイラ(?)で要求されたSQL拾えますよね。 拾えたらそのUPDATE文の妥当性を検証してはどうでしょう。 | ||||||||
|
投稿日時: 2003-10-15 09:02
こんにちは。
表に外部キーが設定されていると、その確認も行いますので、一時的に外部キーを無効にしておくというのも手です。 | ||||||||
|
投稿日時: 2003-10-15 13:37
ぴでさん、Jittaさん、ありがとうございます。
早速プロファイラでトレースを取ってみたところ。。。 UPDATE KYKINFO SET KYKNM = @p1 WHERE ( (JIGYOCD = @p2) AND (KYKNO = @p3) --- ここまででよいのに AND ((KYKNM IS NULL AND @p4 IS NULL ) OR ( KYKNM = @p5 )) AND ((KYKTEL IS NULL AND @p6 IS NULL ) OR ( KYKTEL = @p7 ) AND ((KYKADR IS NULL AND @p8 IS NULL ) OR ( KYKADR = @p9 ) ・・・・・・ と全項目が最初にSELECTした値と等しいかAND条件に入れているようなのです(--; このテーブルが項目数が120個程度あるのですが、それらがすべてWHERE句に 入ってしまっています。 こういった仕様なのでしょうか。。。プライマリキーのみで更新できるようにする よい手がありましたらご教授ください。 -- Jittaさん このテーブルを更新してる間にも、別のセッションから外部キーを使って検索を 行う必要があるのです。 このセッションの中だけ外部キーを無効にする、なんてことはできないですよね? | ||||||||
|
投稿日時: 2003-10-15 14:02
データアダプタの構成で、UpdateやInsert文を自動で作りました?もしそうなら、それが原因です。今、試せるソリューションがないのでうろ覚えですが、データアダプタの構成ウイザードで、途中でSELECT文を作るとき、オプションで全列一致をするかどうかのチェックがあります。これはウイザードを起動すると必ずオンになっているので、毎回オフにしてやらなければなりません(ように思う)。 確かに、複数のセッションが動いてますよね--;。失礼しました。 | ||||||||
|
投稿日時: 2003-10-15 16:45
JittaさんのおっしゃるとおりCommandBuilderを使用しています。
これの仕様だったんですね。 -- 宣言部 Private dadJgyk As New SqlDataAdapter("SELECT * FROM F_JGYKYK", con) Private cbJgyk As New SqlCommandBuilder(dadJgyk) -- UPDATE文作成部 dadJgyk.UpdateCommand = cbJgyk.GetUpdateCommand dadJgyk.Update(dstJgyk, "F_JGYKYK") DataAdapterでSELECT実行時に指定、ということは上記宣言時に行うということでしょうか? これから自分でも調べてみるつもりですが、詳しいやりかたがわかりましたらご教授いただけないでしょうか。 重ね重ね申し訳ありませんが、よろしくお願いいたします。 | ||||||||
|
投稿日時: 2003-10-15 16:57
仕様です。
デザイナ上でデータアダプタの構成ウイザードにより構成する場合は、「オプティミスティック」をオフにできます。 | ||||||||
|
投稿日時: 2003-10-16 12:49
Jittaさんありがとうございます。
やはりできないんですね。とりあえずCommandBuilderで作成したSQL文の WHERE句以降をロジックで置き換えることで対応しました。 これからはCommandBuilderはできるだけ使用しないようにします。 ありがとうございました。 |
1