- 締切済み
<SQLServer2005>実行プランと実行タイムアウト
とある検品システムを作成しているのですが、 「タイムアウトに達しました。操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。」 というエラーメッセージが出て困っています。 環境:SQLServer2005 SP適用なし 検品システムの流れを簡単に示します。 添付図も参考にしてください。 (1)受注データを受注テーブルに取り込む。 (2)出荷できるであろう数量を出荷数量として受注データに反映。 (3)受注テーブルより商品ごとの出荷数量分、検品テーブルに検品データを作成する。 (4)倉庫で商品バーコードを読み込み、シーケンス番号の若い順から検品フラグを0→1にする。 (5)欠品商品ビューより欠品帳票を作成する。 問題は(5)の欠品商品ビューよりselectしてくる所で発生します。 納品日を条件に取ってくるのですが、大したデータ件数もない(受注テーブル1万件、検品テーブル4万件)のに、ある納品日を条件にした時のみ、実行タイムアウトとなってしまいます。 原因を色々調べたところ、対象の納品日条件の時のみ、実行プランが異なっているようです。かといって、上記の通りそれほどデータ件数はないのですが,なぜそんなに時間がかかるのか…。 欠品情報を取得してくるselect文は 『select * from 欠品商品ビュー where 納品日 = '09/01/19'』 パラメータが違うだけで、実行プランはキャッシュされ、再利用されると思っているのですが、どうして異なるのでしょうか? 『dbcc freeproccache』でキャッシュを削除しても、また異なる実行プランが作成されます。 データのばらつき等関係あるのでしょうか? また、現状応急処置としてCommandTimeoutの設定を長くすることで対応しましたが、CommandTimeoutの設定を長くしたことによって、一般的に問題となるようなことはあるのでしょうか? 長文で申し訳ありません。 どんな些細なことでもかまいません。 何かお気づきになることがありましたら、教えてください。 よろしくお願いいたします。 <欠品商品ビューの構成文> select T1.商品, T1.受注数量, (T1.受注数量 - T2.検品数量) as 欠品数量 from 受注テーブル as T1,( select 商品, isnull(sum(検品フラグ),0) as 検品数量 from 検品テーブル group by 商品 ) as T2 where T1.商品 = T2.商品 and T1.受注数量 > T2.検品数量 union all select T1.商品, T1.受注数量, T1.受注数量 as 欠品数量 from 受注テーブル as T1 where T1.出荷数量 = 0
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- nora1962
- ベストアンサー率60% (431/717)
> 納品日」のインデックスですが、ビューに作成すればいいのでしょうか? > それとも受注テーブルでしょうか? 受注テーブルです。
- nora1962
- ベストアンサー率60% (431/717)
CREATE VIEW 欠品商品ビュー AS SELECT * FROM ( select T1.商品, T1.受注数量, ( SELECT T1.受注数量 - sum(T2.検品フラグ) FROM 検品テーブル T2 WHERE T1.商品=T2.商品 GROUP BY T2.商品 ) AS 欠品数量, T1.納品日 from 受注テーブル as T1 ) AS T3 WHERE 欠品数量>0 UNION ALL select T1.商品, T1.受注数量, T1.受注数量 as 欠品数量, T1.納品日 from 受注テーブル as T1 where T1.出荷数量 = 0 とか CREATE VIEW 欠品商品ビュー AS SELECT T4.商品, T4.受注数量, T4.受注数量-T4.検品数量 AS 欠品数量, T4.納品日 FROM ( SELECT * FROM ( select T1.商品, T1.受注数量, ISNULL( ( SELECT sum(T2.検品フラグ) FROM 検品テーブル AS T2 WHERE T1.商品=T2.商品 GROUP BY T2.商品 ),0) AS 検品数量, T1.納品日 from 受注テーブル as T1 ) AS T3 WHERE (受注数量-検品数量)>0 ) AS T4 で試してみても同じですか。 後、「納品日」には索引張ってください。
お礼
ありがとうございます。 せっかく答えていただきながら、1ヶ月に1度起きるか起きないかの現象ですぐに試せない状況です、誠に申し訳ございません。 というのも、問題発生の翌日になると、別途開発したクリーンアップ処理が働き、受注テーブルの不要データが削除されます。 すると、ほんの少しテーブルデータが変わるだけで問題が解消されてしまいます。 それがデータのばらつきによる原因かと思う理由です。 また、問題発生時のデータをバックアップして開発環境のDBにインポートしてみても問題は発生しません。 いくつかの受注データを取り込んでできた受注テーブルと、それをエクスポートして一括でインポートした受注テーブルとは内部的にデータの 持ち方が違うのでしょうか? ただ、実システムではより多くの項目があり、欠品商品ビューだけでなく、検品商品ビューや欠品リストビューなどもあります。 実行タイムアウトエラーが起きているビューは欠品商品ビューと欠品リストビューで、安易ですが検品商品ビューとの違いは「UNION ALL」以降があるかないかです。 そう考えると、nora1962様の二つ目のCreateView文を試してみたいところです。 「納品日」のインデックスですが、ビューに作成すればいいのでしょうか?それとも受注テーブルでしょうか?
お礼
遅くなりました。 度々ありがとうございます。 うかがった回答をもとに実行タイムの計測、短縮を図っていきたいと思います。