- PR -

ストアドプロシージャ実行時のタイムアウト

投稿者投稿内容
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 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

上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2007-11-07 18:21
 え〜と、タイムアウトが発生していると言う事ですが、タイムアウト自体は
VB6.0からSQLサーバーにSQLを流す上での時間制御だと思います。
(コネクションやら何やらの)

で、単純に2回目以降が速いのは、(コネクション等が)タイムアウトになりはしたが、
サーバー上でストアードの処理が終了し、メモリ上のキャッシュに前回(1回目の)
結果が残っている為だと思います。

残念ながらVB6.0での直接SQLについてタイムアウトが発生しない理由は判りません。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-07 22:09
タイムアウトが発生するならタイムアウトを伸ばしましょうwww。
接続文字列かConnectionのプロパティで変更できるはずです。
直接SQLで問題ないのはそもそもSPより早く終了するのでしょう。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 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 ]
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2007-12-19 13:58
引用:

ともこさんの書き込み(投稿日時: 2007-12-19 13:31)より
キャッシュに残るのは、具体的には@「SELECTされた抽出結果」、A「コンバイルされたSELECT文字列」のどちらになるのでしょうか?@、Aでない場合、どういった形で残るのでしょうか?
私の推測では、@が残る事は考えにくいので、Aが残ると2回目は短時間で結果を得られると思います。(推測なのでまったく宛てにはなりませんが。)
しかし、ストアドプロシージャとして事前にコンパイルされているので1回目の実行時にはすでにAがサーバー上に残っているのでは?と思います。


基本的には@Aの両方がメモリに残ります(当然空きが少なくなれば古いものから消え
ますが)。
但し、Aの『コンパイルされたSELECT文字列』が残っていても対して早くなりません、
大抵はコンマ数秒の差でしかないですね。

劇的に速くなるのは既にデータがキャッシュに残っている場合です。
この場合だとハードディスクからデータを読み取らずに、メモリからデータを取り出す
ので速くなります。

引用:

ともこさんの書き込み(投稿日時: 2007-12-19 13:31)より
ストアドは「命令を事前にコンパイルし、サーバーに保存されているもの」だと思うのですが、ストアドBのような多分岐もコンパイルされて保存されるのでしょうか?
両方ともコンパイル済みの場合、ストアドAを実行する場合とストアドBに対してPara1=1で実行する場合とではサーバーの処理自体は同じと考えて良いでしょうか?


動的SQLでなければ(静的SQL)コンパイル済みの状態となるので、実行速度に差は無い
ですね。
ですのでストアドAとストアドB(Para1=1時)は同じとみて問題ありません。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2007-12-19 15:35
上総さん、すみません!
色々ごちゃごちゃ書き込んでしまい後から削除した内容(投稿日時: 2007-12-19 13:31)についてもご丁寧に回等していただいて恐縮です。

やはり抽出結果がメモリ上のキャッシュに残っていたからでしょうか?
投稿日時: 2007-12-19 13:53の件に関しては何かご意見はありますでしょうか?

私事ですが、社内で開発・運用を行なっているアプリケーションで今回のストアドプロシージャを使用しているのですが、一回目の実行で「タイムアウト」もしくは「切断されないまでも長時間の待ち」が発生するようですと運用に支障が出ます。
一回目の実行から正常にストアドを実行出来ないと困ります、何か手は無いでしょうか?
こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2007-12-19 15:56
> 一回目の実行から正常にストアドを実行出来ないと困ります、何か手は無いでしょうか?
インデックス付きビューを使ってみてはいかがでしょうか?

> 抽出結果がメモリ上のキャッシュに残っていた
のと、同じような効果を見込めるかもしれません。


あるいは、擬似的なキャッシュ相当のテーブルを自前で用意するか。
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2007-12-19 16:38
引用:

ともこさんの書き込み(投稿日時: 2007-12-19 15:35)より
私事ですが、社内で開発・運用を行なっているアプリケーションで今回のストアドプロシージャを使用しているのですが、一回目の実行で「タイムアウト」もしくは「切断されないまでも長時間の待ち」が発生するようですと運用に支障が出ます。
一回目の実行から正常にストアドを実行出来ないと困ります、何か手は無いでしょうか?



対症療法ですが、毎日業務開始前に全てのパラメータを使用して、ストアードを実行
するのはどうでしょうか?
一応ストアード内の全てのデータをメモリに展開出来ることが条件となりますが。

今回提示されたストアードが全件(WHERE句無し)抽出なのも痛い所です、WHERE句付き
であればインデックスを使用する事で検索速度を上げる事も可能ですが。
(無闇やたらとインデックスを付けると、返って遅くなることもありますが)

後はデータベースの物理設計を見直すしか無いかと思います。
念のための質問ですが、今回ストアードで使用しているテーブル(ALL_V_0001・
AA_V_0004・AA_V_0005・MM_V_0001・MM_V_0002・FI_V_0001)は、全て同じデータ
ファイル上に格納されてたりしますか?
(何故か一個のデータファイルに全てのテーブルを格納しているのではないかと、
 背筋に冷たいものが流れてますが・・・・)

一応サーバー構成(HDDが幾つでRAIDが1とか、メモリ・CPU・ディスクの回転速度等)を
提示して頂ければ何とかなるかも知れません。

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