- PR -

SqlException,タイムアウトに達しました・・・・

投稿者投稿内容
みのる
大ベテラン
会議室デビュー日: 2003/07/03
投稿数: 100
投稿日時: 2004-08-15 15:09
こんにちは。

以下のエラーで大変困っております。

SqlException,タイムアウトに達しました。
操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。

内容は単純なDELETE文の実行です。

Private m_cn As SqlConnection
Private m_cm As SqlCommand
Private m_trn As SqlTransaction
Private m_strSQL As String

m_strSQL = ""
m_strSQL += "DELETE"
m_strSQL += " FROM テーブル名"
m_strSQL += " WHERE 条件"

'DB接続
m_cn = New SqlConnection
m_cn.ConnectionString = c_DbConstr & _
c_DbUser & _
c_DbPasswordm_strDbPassword)
m_cn.Open()

'コマンドオブジェクトの生成
m_cm = m_cn.CreateCommand()

'トランザクションの開始
m_tran = m_cn.BeginTransaction(IsolationLevel.ReadCommitted)
m_cm.Transaction = m_trn

'SQLステートメントの作成
m_cm.CommandText = m_strSQL

'実行
m_cm.ExecuteNonQuery()

'コミット
m_trn.Commit()
blnTran = True


扱うデータの件数を増やしテストをしています。
1万件、5万件、10万件、50万件

10万件までのテストはできるのに、
50万件のテストで上記のエラーが発生します。
直接SQL文を実行した場合は、エラーが発生しません。

言語 VB.NET
EXEファイル+クラスファイル(SQL文発行)
  
DB  SQLServer2000

よろしくお願いします。






[ メッセージ編集済み 編集者: みのる 編集日時 2004-08-15 15:55 ]
CARA
会議室デビュー日: 2004/04/07
投稿数: 2
投稿日時: 2004-08-15 15:47
ConnectionTimeoutの設定を変えてみるのはどうでしょうか。
みのる
大ベテラン
会議室デビュー日: 2003/07/03
投稿数: 100
投稿日時: 2004-08-15 16:29
CARAさん、ありがとうございます。

>ConnectionTimeoutの設定を変えてみるのはどうでしょうか。

早速、以下の通りにしてみました。
m_cn.ConnectionString = m_strDbConstr & _
"UID=" & m_strDbUser & ";" & _
"PWD=" & m_strDbPassword & ";" & _
"Connect Timeout = 300"

m_cm.CommandTimeout = 300

残念がら、同じエラーが出てしまいました。。。
えムナウ
大ベテラン
会議室デビュー日: 2004/06/10
投稿数: 187
お住まい・勤務地: 東京
投稿日時: 2004-08-15 17:02
>扱うデータの件数を増やしテストをしています。
>1万件、5万件、10万件、50万件
>10万件までのテストはできるのに、
>50万件のテストで上記のエラーが発生します。
>直接SQL文を実行した場合は、エラーが発生しません。
直接SQL文を実行した場合というのはSQLクエリアナライザとかのツールですか?
各データ件数での直接SQL文を実行した場合の所要時間はどれ位でしょうか?
_________________
えムナウ Microsoft MVP for Visual Developer - C#,2005/01-2007/12
えムナウのプログラミングのページ Blog1 Blog2
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2004-08-15 23:24
引用:

10万件までのテストはできるのに、
50万件のテストで上記のエラーが発生します。



多量の delete に時間がかかるのは、ある程度仕方ありません。

タイムアウトを延ばして50万件のテストを通過したとしても、100万件のテストは通過しないかもしれないし、高負荷時には50万件の処理でもタイムアウトするかもしれません。

こういう場合、設計自体を見直すのが最も効果的です。

私が良く使う手は

・各レコードに「削除フラグ」の列を追加する。
・通常の「削除」処理は「削除フラグ」を true にするだけ。
・夜間バッチなどで「削除フラグ」が true なものを一括 delete する。

です。

バッチが使えない場合は、新規レコードの挿入時に削除マークのついたレコードを1個以上 delete するなどの工夫が必要です。

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
えムナウ
大ベテラン
会議室デビュー日: 2004/06/10
投稿数: 187
お住まい・勤務地: 東京
投稿日時: 2004-08-16 01:34
ひょっとしたらこの処理自体がバッチ処理ではないですか?
バッチ処理でしたらストアドプロシージャで運用することを検討してみてください。
_________________
えムナウ Microsoft MVP for Visual Developer - C#,2005/01-2007/12
えムナウのプログラミングのページ Blog1 Blog2
みのる
大ベテラン
会議室デビュー日: 2003/07/03
投稿数: 100
投稿日時: 2004-08-16 17:20
たくさんの方々、いろいろとご指導ありがとうございます。

そして、遅れてしまってすみません。

えムナウさんのアドバイスで、タイムアウトの時間を増やしてみました。
50万件成功です。
100万件は失敗です。

渋木宏明(ひどり)さんの言うとおりです。。

残念ながら
設計上、渋木宏明(ひどり)さんの方法はちょっと難しいと思われます。

えムナウさんの「ストアドプロシージャで運用」というのは
タイムアウトを気にしなくて言いのでしょうか?

ちらっと調べたのですが、
「DataReaderにストアドプロシージャを渡すせばいい」と
どこかのHPに書いてありました。

っていうことは、タイムアウト気にしないといけないのでは??

お手数ですが、.NETではどのようにストアドプロシージャで運用するのか
教えていただけませんか?
(VB6.0と同じでいいのでしょうか?)


Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-08-16 19:24
 いったんインデックスや外部参照を無効にすれば、早くはなります。どれくらい効率があがるかは、張ってあるインデックスなどによります。

スキルアップ/キャリアアップ(JOB@IT)