これが重複している場合、私は容赦します。私が見つけた最も近いものはRandom timeout running a stored proc - drop recreate fixesでしたが、ストアドプロシージャの再コンパイルについての回答は当てはまりません。破損したAzure SQLストアドプロシージャは、ドロップで再作成することしかできませんでした
私はAzure Webアプリケーションのフロントエンドからのトラフィックが多いAzure SQLデータベース(最新バージョン)を持っています。 Azure SQLデータベースのインデックスを再構築するために、データベースのサイズとパフォーマンスを制御するのに大いに役立つと思われる夜間のリモートジョブがあります。
通常、インデックスの再構築には約20分かかります。昨夜、2時間後にタイムアウトしました。そのバッチ内のエラーハンドラはエラーを記録しませんでした。
すぐにインデックスを再構築した後、ある特定のストアドプロシージャが、それを呼び出すすべてのクライアントのタイムアウトを開始します。同じテーブルを使用している他のストアドプロシージャに問題はありませんでした。私が問題を発見したら、すぐに戻るためにストアドプロシージャを変更することによって、すべてのタイムアウトと中断されたプロセスを緩和することができました。ストアドプロシージャを再び正常に動作させるために変更した場合、問題はすぐに再現されました。私の理解は、ストアドプロシージャを変更すると再コンパイルが強制されたが、それは修正されなかったということです。
最終的に、私は完全に元のコードでプロシージャを削除して再作成し、問題は解決されました。
この手順とそれが使用するスキーマは、何ヶ月間も完全に安定しています。迅速かつ成功裏に返すクエリウィンドウで同じ選択を実行
exec dbo.uspActivityGet 'AF3EA01B-DB22-4A39-9E1C-D096D2DF1215'
:手順はこのような何かとの時間をたむろしてだろうが
CREATE Procedure [dbo].[uspActivityGet] (@databaseid uniqueidentifier) AS
begin
SET NOCOUNT ON;
--There may be writing activities to the table asynchronously, do not use nolock on tblActivity - the ActivityBlob might be null in a dirty read.
select top 100 a.Id, h.HandsetNumber, a.ActivityBlob, a.ActivityReceived
from dbo.tblDatabases d with(nolock) join dbo.tblHandsets h with(nolock) on d.DatabaseId = h.DatabaseId join dbo.tblActivity a on h.Id = a.HandsetId
where d.DatabaseId = @databaseid and a.ActivitySent is null
order by a.ActivityReceived
end
:手順自体は非常に簡単です
declare @databaseid uniqueidentifier; set @databaseid = 'AF3EA01B-DB22-4A39-9E1C-D096D2DF1215'
select top 100 a.Id, h.HandsetNumber, a.ActivityBlob, a.ActivityReceived
from dbo.tblDatabases d with(nolock) join dbo.tblHandsets h with(nolock) on d.DatabaseId = h.DatabaseId join dbo.tblActivity a on h.Id = a.HandsetId
where d.DatabaseId = @databaseid and a.ActivitySent is null
order by a.ActivityReceived
これを今後どのように防ぐことができますか?ありがとうございました。
編集 - 実行中のプロセスを表示するために使用クエリを追加 - 実行計画のスクリーンショット
編集]を追加します。中断された状態で約150人が推測されていましたが、それらはすべて同じストアドプロシージャ - uspActivityGetに属していました。また、Data IO Percentageは、ピーク需要時間で通常20〜40%稼働している間は、全期間にわたって最大値に達しました。私は待っているタイプが何だったか思い出さない。これを表示するために使用されるクエリは次のとおりです。
select * from sys.dm_Exec_requests r with(nolock) CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) order by r.total_elapsed_time desc
編集 - それは今晩も起こった。問題が発生している間の同じ手順の実行計画です。再度プロシージャを削除して作成した後、実行計画は正常に戻り、問題は解決されました。
問題が発生している間、同じクエリを実行しているsp_executesqlの実行には約5分かかりました。 uspActivityGetの約50インスタンスが待機タイプSLEEP_TASKまたはIO_QUEUE_LIMITで中断されました。
おそらく次の質問は、実行計画に対してこれを実行しているインデックスの再構築またはその他の夜間のメンテナンスはなぜですか?
他の手順では、全く同じ結合を使用することはできません。多分、異なる手順が異なるインデックスを活用するでしょうか? 'd.DatabaseId'はインデックスされていますか? 'NOLOCK'ヒントは必須ですか?索引の問題がそのヒントによって隠されている可能性がありますか?プロシージャが失敗したときにSSMSからクエリを実行するとどうなりますか? – Paolo
@Paoloは、クエリウィンドウで同じselect文を実行すると、速やかに正常に戻ります。 – RJBreneman
procがブロックされているか、非常に長い間、何か他の何かをしているかどうかを知ることができますか?クエリで定数としてGUIDを指定すると、SQL Serverがクエリにかかるコストを変更し、テストで両方のクエリが同じように実行されないようにします。 sp_executesql N ' - あなたのクエリ'、N '@ databaseid uniqueidentifier'、 '--your param'を使ってテストを行い、まだ高速に実行されているかどうかを確認してください。また、実行計画を共有して、SQL Serverが何を考えているかを確認することができます。 – SQLmojoe