SQL Serverエージェントジョブに関する手順があり、このジョブは待機統計CXCONSUMERでトランザクションで何時間もハングし始め、完了しませんでした。問題は、ハングしていることに気付いた後、ジョブを強制終了して手動で開始し、ジョブが正常に機能して完了したことです。しかし、現時点では、手動で開始することも、SQLエージェントジョブで開始することも、CXCONSUMERを使用して完了したり待機したりすることはありません。
Sp_who2、sp_whoisactive、およびsqlサーバープロファイラーによると、待機中のアクティブなロックはありません。それは、CXCONSUMERとプロセッサ時間を生み出し続け、基本的に何もしません。ここに3時間後の実行計画があります-
その他の症状は、このジョブの実行時にtempdbがプロパティを介してアクセスできないことです。このエラーは、「プロパティSpaceAvailableはデータベース '[tempdb]'には使用できません。このオブジェクトには存在しないか、不十分なために取得できない可能性があります。 tempdbに使用可能なスペースがあるにもかかわらず、「アクセス権」。
この問題であなたの助けに感謝します。
この質問には、実際には2つの質問があります。
#2から始めましょう。
あなたはこのエラーを受け取ります:
要求されたダイアログを表示できません。 (SqlMgmt)プロパティSpaceAvailableはデータベース '[tempdb]'では使用できません。このプロパティはこのオブジェクトに存在しないか、アクセス権が不十分なために取得できない可能性があります。 (Microsoft.SqlServer.Smo)
これは、トランザクション内に一時テーブルを作成すると発生します。 CREATE TABLE
は、クエリをブロックしてデータベースプロパティウィンドウに入力するシステムテーブルのメタデータロックを保持し、そのダイアログを開くとタイムアウトしてこのエラーが表示されます。
このステートメントをSSMSで実行し、同時にtempdbのプロパティウィンドウを開こうとすると、うまく開くと思います。
SELECT o1.object_id
INTO #blep
FROM sys.objects o1
CROSS JOIN sys.objects o2
CROSS JOIN sys.objects o3
CROSS JOIN sys.objects o4
CROSS JOIN sys.objects o5;
ただし、同じクエリがトランザクションにドロップされると、取得したと報告した上記のエラーが発生します。
BEGIN TRANSACTION
SELECT o1.object_id
INTO #blep
FROM sys.objects o1
CROSS JOIN sys.objects o2
CROSS JOIN sys.objects o3
CROSS JOIN sys.objects o4
CROSS JOIN sys.objects o5;
プランに含まれている以上のコードを提供しなかった場合でも、上記の例と同様に、動作はトランザクション内でSELECT...INTO
が発生していることを示しています。
Tempdb内のシステムテーブルがブロックされるため、トランザクション内に一時テーブルを作成することをお勧めしますnever。これは、データベースプロパティウィンドウの問題などの運用上の問題に加えて、同時実行性に影響します。
手順でトランザクションを使用する必要がある場合は、トランザクションの外側にテーブルを作成してから、トランザクションを開始して必要な作業を行う必要があります。 SELECT...INTO
の動作に依存してスキーマを定義する場合(動的/不明なスキーマなど)、SELECT...INTO...WHERE 1=2;
を使用して空のテーブルを作成し、その後でトランザクションを開始して作業を行います。
さて、他の質問に:
sp_whoisactive
の出力のどの行がクエリに関連しているのかわかりません。それらすべて? Session_id 797は高いCXCONSUMER
待機を示しており、2時間実行されています。それが問題のあるセッションだと思います。 2h 12miの「実」時間(132分)で、約5790万ミリ秒のCPUサイクル(967分)を実行しました。これは、「実際の」時間の約7倍のCPU時間です。これは、並列処理の実行でビジーであることを示しています。
これはSAPデータベースであることがスキーマからわかります。 SAPスキーマは少し変わったものであり、MANDT
列はすべてのクラスター化複合インデックスの先頭列です。この列は基本的に「会社コード」であり、さまざまな子会社のデータを分離するために使用されます。 SAPは、EVERYクエリの結合/フィルター述語内にこの列を提供して、適切な会社のデータを処理できるようにします。会社が別々の子会社のために別々の本を保管していない場合、MANDT
列は常にまったく同じ値になります。
非選択的な述語が提供されるため、SQL Serverをだまして、実際にテーブルを実行しているときに、クラスター化された主キーにseekを表示することができますscan。すべての行のAMTWO
に対してMANDT
の値があり、AND MANDT = 'AMTWO'
に対してクエリを実行した場合、オプティマイザmightは、「ねえ、それがPK、私はそれを求めることができます!」しかし、実際には、その値の最初の出現(つまり、最初の行)にシークし、その値の最後の出現(つまり、最後の行)まで読み取ります。すべての行はまったく同じ値なので、計画ではシークとして表示されますが、スキャンすべての行にする必要があります。
実際には、使用するインデックスの方が優れていますが、SQL Serverは、別のインデックス(またはインデックスの組み合わせ)の方がパフォーマンスが良いことを認識していません。
さらに、SQL Serverのバージョンと トレースフラグ2389 を使用しているかどうかに応じて、SAPは、トランザクションデータのキーとして日付を多用することに関連する「昇順キーの問題」に悩まされることがよくあります。
これらの問題はどちらも、SAPデータベースで積極的に 統計の更新 を実行することで解決できます。
確かに、統計よりもクエリで何かが起こっている可能性がありますが、SAPでの私の経験に基づいて、最新の統計が私の優先リストの一番上にあることを確認します。
「トランザクションで何時間もハングアップし始めた」とあなたは言います...それは以前どのくらいの速さで実行されていましたか?同じ量のデータを処理するのは高速でしたか?計画は、#repositioning
で100万行、#stock
で20万行、MSEG
---で6500万行が機能していることを示しているため、クエリは期待できません。そもそも非常に速い。
統計を更新した後、actualIO&このコードの実行に必要なCPUコスト)をキャプチャしたいと思います Plan Explorer のようなものを使用すると、特にSQL Serverが「悪い」計画を選択し、より優れた/より速い計画が存在するがそれがなかった場合に、問題の洞察が得られることがよくあります。選択されていません。