- - PR -
ストアドプロシージャ実行時のタイムアウト
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-11-07 16:59
いつもお世話になります。
現在、VB6.0で作成したアプリケーションから、SQLサーバー2000(SP4)のデータをストアドプロシージャにて取得しています。(ストアドプロシージャとその使用方法は下記を参照ください。) ストアドプロシージャを実行する際、最初の1回(朝出社してからの1回目など)は実行後に必ずタイムアウトエラーになってしまいます。しかし、同様のストアドプロシージャをもう1度実行すると、今後はタイムアウトエラーは表示されず正常にデータを取得できます。 何故このような現象が発生してしまうのか不明です、どなたか原因と解決方法をご存知の方がおられましたらアドバイスをお願いします。 また参考までに、VB6.0で作成したアプリケーションからSQLサーバー2000(SP4)のデータを取得する際、ストアドプロシージャを使用しない方法では最初の1回もタイムアウトする事はありません。 ■ストアドプロシージャ CREATE Procedure dbo.ALL_S_0001 ( @パターン varchar(3) ) As /*プラント*/ IF @パターン='D1' BEGIN SELECT * FROM ALL_V_0001 TW GOTO jump_point END /*資産クラス*/ IF @パターン='D4' BEGIN SELECT * FROM AA_V_0004 AN GOTO jump_point END /*指図書タイプ*/ IF @パターン='D9' BEGIN SELECT * FROM AA_V_0005 AN GOTO jump_point END /*購買組織*/ IF @パターン='D19' BEGIN SELECT * FROM MM_V_0001 T02 GOTO jump_point END /*購買グループ*/ IF @パターン='D20' BEGIN SELECT * FROM MM_V_0002 T0 GOTO jump_point END /*ワークリスト*/ IF @パターン='D21' BEGIN SELECT * FROM FI_V_0001 AT GOTO jump_point END jump_point: GO ■ストアドプロシージャの実行ロジック ' ストアドプロシージャ接続設定 DATABASE1 = "CLC_R3" ' DATABASE1 = "CLC_NPTS" 'パラメータの指定 ADODB_Open ("ALL_S_0001") 'ADODB接続オープン Set Conn1 = New ADODB.Connection Set RS = New ADODB.Recordset Conn1.CursorLocation = adUseClient Conn1.Open "Driver={SQL Server};" & _ "SERVER=Rapsap\CLC_DATA;" & _ "DATABASE=" & DATABASE1 & ";" & _ "User Id=nkuser;" & _ "Password=nkpass" cmd.CommandText = Stored 'ストアドプロシージャの指定゙ cmd.ActiveConnection = Conn1 '接続方法の指定 cmd.CommandType = adCmdStoredProc 'ストアドプロシージャの呼び出しコマンド cmd.Parameters(1).Value = PtnV RS.Open cmd, , adOpenStatic End Sub | ||||||||
|
投稿日時: 2007-11-07 18:21
え〜と、タイムアウトが発生していると言う事ですが、タイムアウト自体は
VB6.0からSQLサーバーにSQLを流す上での時間制御だと思います。 (コネクションやら何やらの) で、単純に2回目以降が速いのは、(コネクション等が)タイムアウトになりはしたが、 サーバー上でストアードの処理が終了し、メモリ上のキャッシュに前回(1回目の) 結果が残っている為だと思います。 残念ながらVB6.0での直接SQLについてタイムアウトが発生しない理由は判りません。 | ||||||||
|
投稿日時: 2007-11-07 22:09
タイムアウトが発生するならタイムアウトを伸ばしましょうwww。
接続文字列かConnectionのプロパティで変更できるはずです。 直接SQLで問題ないのはそもそもSPより早く終了するのでしょう。 | ||||||||
|
投稿日時: 2007-12-19 13:53
返答が遅くなりすみませんでした!
(上総さんのコメントより) >単純に2回目以降が速いのは、(コネクション等が)タイムアウトになりはしたが、 >サーバー上でストアードの処理が終了し、メモリ上のキャッシュに前回(1回目の) >結果が残っている為だと思います。 「同じストアドを2回実行すると大抵2回目の方が1回目より早く結果を表示出来るのは、メモリ上のキャッシュに1回目の結果が残っているから」という事でしょうか? しかし、ストアドAとストアドBがあったとし、以下のような現象が起こる事があります。 ケース@ 1.ストアドA実行 → タイムアウト 2.ストアドA実行 → 正常に結果を表示 ・・・2回目だからキャッシュに結果がある為? ケースA 1.ストアドB実行 → 正常に結果を表示 2.ストアドA実行 → 正常に結果を表示 ・・・ストアドAは1回目なのでキャッシュは無いはずなのに結果を表示できた。 その為、1回目のキャッシュのおかげで2回目が成功したというよりは、1回何かのストアドを実行したのでクライアントとサーバーの接続確認が終了し2回目はスムーズに行なえた、といった印象を受けます。このような認識は正しいのでしょうか? [ メッセージ編集済み 編集者: ともこ 編集日時 2007-12-19 13:55 ] | ||||||||
|
投稿日時: 2007-12-19 13:58
基本的には@Aの両方がメモリに残ります(当然空きが少なくなれば古いものから消え ますが)。 但し、Aの『コンパイルされたSELECT文字列』が残っていても対して早くなりません、 大抵はコンマ数秒の差でしかないですね。 劇的に速くなるのは既にデータがキャッシュに残っている場合です。 この場合だとハードディスクからデータを読み取らずに、メモリからデータを取り出す ので速くなります。
動的SQLでなければ(静的SQL)コンパイル済みの状態となるので、実行速度に差は無い ですね。 ですのでストアドAとストアドB(Para1=1時)は同じとみて問題ありません。 | ||||||||
|
投稿日時: 2007-12-19 15:35
上総さん、すみません!
色々ごちゃごちゃ書き込んでしまい後から削除した内容(投稿日時: 2007-12-19 13:31)についてもご丁寧に回等していただいて恐縮です。 やはり抽出結果がメモリ上のキャッシュに残っていたからでしょうか? 投稿日時: 2007-12-19 13:53の件に関しては何かご意見はありますでしょうか? 私事ですが、社内で開発・運用を行なっているアプリケーションで今回のストアドプロシージャを使用しているのですが、一回目の実行で「タイムアウト」もしくは「切断されないまでも長時間の待ち」が発生するようですと運用に支障が出ます。 一回目の実行から正常にストアドを実行出来ないと困ります、何か手は無いでしょうか? | ||||||||
|
投稿日時: 2007-12-19 15:56
> 一回目の実行から正常にストアドを実行出来ないと困ります、何か手は無いでしょうか?
インデックス付きビューを使ってみてはいかがでしょうか? > 抽出結果がメモリ上のキャッシュに残っていた のと、同じような効果を見込めるかもしれません。 あるいは、擬似的なキャッシュ相当のテーブルを自前で用意するか。 | ||||||||
|
投稿日時: 2007-12-19 16:38
対症療法ですが、毎日業務開始前に全てのパラメータを使用して、ストアードを実行 するのはどうでしょうか? 一応ストアード内の全てのデータをメモリに展開出来ることが条件となりますが。 今回提示されたストアードが全件(WHERE句無し)抽出なのも痛い所です、WHERE句付き であればインデックスを使用する事で検索速度を上げる事も可能ですが。 (無闇やたらとインデックスを付けると、返って遅くなることもありますが) 後はデータベースの物理設計を見直すしか無いかと思います。 念のための質問ですが、今回ストアードで使用しているテーブル(ALL_V_0001・ AA_V_0004・AA_V_0005・MM_V_0001・MM_V_0002・FI_V_0001)は、全て同じデータ ファイル上に格納されてたりしますか? (何故か一個のデータファイルに全てのテーブルを格納しているのではないかと、 背筋に冷たいものが流れてますが・・・・) 一応サーバー構成(HDDが幾つでRAIDが1とか、メモリ・CPU・ディスクの回転速度等)を 提示して頂ければ何とかなるかも知れません。 |