同一の(?)SQL Server 2005マシン。クエリは一方で2秒、他方で15分かかります


12

環境:

SQL Server 2005を実行している2つの32ビットWindows Server 2003 R2マシンがあります。ハードウェア構成は、Xeon 5160 CPU、4GB RAM、13GB RAID0を備えた同一サーバーです。AWEおよび/ 3GBフラグは有効ではありません。

サーバーは、事前に定義されたインストールチェックリストを使用して並列にセットアップされ、インストールされたすべてのソフトウェアは両方のマシンで同じです。

確認する必要があるSQLサーバーのインストール設定とパッチレベルはすべて同じです。1つの違いは、TEMPDBが高速マシンで400MB、低速マシンで1.2GBであることです。ただし、どちらの場合も、TEMPDBの割り当ては行われていません。

問題:

一方では2秒、もう一方では15分で実行されるストアドプロシージャがあります。追加の15分間、ディスクアクティビティはほとんどないか、メモリ使用量は変化しませんが、1つのCPUコアが常に100%に固定されます。

この動作は、データベースが一方からバックアップされ、他方に復元された場合でも持続します。

これはストアドプロシージャであるため、アクティビティモニタとプロファイラは、ストアドプロシージャのどこでこの高CPUアクティビティが発生しているかについての詳細を表示しません。

質問:

他に何を見るべきでしょうか?

ファローアップ:

スローは、次のカーソル定義のFETCH NEXTステートメントで発生します。

DECLARE C CURSOR FOR
    SELECT X, Y
    FROM dbo.A
    WHERE X NOT IN (SELECT X FROM dbo.B)
    AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...

各FETCHステートメント(約1000行のみを含むテーブル)では、約7.25分が必要です。(いいえ、なぜ2つ続けて行われるのかわかりません。開発者に尋ねる必要がありますが、両方のサーバーで正しく実行されます)。

Virtual Readsが本当に高いように見えるので、私はその「NOT IN(SELECT ...)」について少し疑っています。


dbo.Bのレコードはどのようになり、dbo.BXはインデックス付けされますか?
マークストリースミス

1
これと一緒に行った場合、パフォーマンスの違いがあるかどうかに興味があります:dbo.axを選択し、dbo.aからdbo.ayを選択しますz <= 0
DForck42

もう1つ考えてみてください。カーソルフェッチが原因で速度が低下していることは確かですか?これは、実行計画(推定に関するすべて)またはプロファイルトレースから決定していますか?
マークストーリースミス

これはプロファイルトレースからのものです。
リアンデンキ

実行計画は同じですか?それらの1つが不適切な実行計画を使用している可能性があります。
ゼーン

回答:


7

待機やキューなどのパフォーマンストラブルシューティングの方法論を使用して、CPUの高消費の理由を特定し、ボトルネックが特定されたら適切なアクションを推奨できます。


6

SQL Serverは、他のボックスで別の計画を選択しています。

通常、復元すると統計に基づいて問題が削除されるため、サーバーの違いを確認します。

最初にいくつかの粗いチェック。想定しない:チェック

  • SQL Serverの設定がsys.configurationで同じであることを確認してください例:最大次数または並列処理)
  • DBCC USEROPTIONSを実行して、実行時にANSI設定が異なるかどうかを確認します(ANS設定は選択したプランに影響を与える可能性があります)
  • WindowsとSQL Serverのログを確認して、問題があるかどうかを確認します

次に、Remusの答えに従って、深い端にジャンプします。


ヒントをありがとう。sys.configurationsとDBCC USEROPTIONSは両方とも2台のマシンで同一です。WindowsまたはSQLサーバーのログにエラーや警告はありません。

1
また、同じデータベースレイアウトを実行しますか?(インデックスの再構築など)で最適化を行う管理者の計画はありません。データベースは関連するオブジェクトに対して同じ統計を持ち、同じディスクレイアウトですか?同じパッチレベル?
トムトム

はい、同じディスク、DBレイアウト、およびパッチレベル。実際、高速マシンのデータベースは低速マシンから復元されたバックアップです。そして、私が見る限り、変化する管理計画はありません。
リャンデンキ

6

他のすべてが等しい場合、(@ gbnの答えによると)各サーバーで異なる実行計画が生成されている可能性があります。アカデミックな演習として、両方の計画を見て、各サーバーの計画キャッシュからそれらを取得し、可能であれば質問に追加することは興味深いでしょう。次に、パフォーマンスの大きな変動を引き起こしている計画の違いを特定できます。

簡単な修正については、USE PLANヒントを参照してください。これにより、高速サーバーから低速サーバー上のストアドプロシージャに適切なプランを添付できます。

編集:次の更新re:カーソル

他の回答で言及されていないことを試してみるためのクエリの他のバリエーション:

DECLARE C CURSOR FOR
    SELECT X, Y
    FROM dbo.A
    WHERE NOT EXISTS (SELECT 1 FROM dbo.B WHERE dbo.B.X = dbo.A.X)
    AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y

これは良いアドバイスです。クエリプランを確認しています。実際、ストアドプロシージャの速度低下はカーソルに関係しているようです。編集を参照してください。
リャンデンキ

4

ユーモアを交えて、交換してみてください:

DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0

これとともに:

DECLARE C CURSOR FOR
SELECT 
    X, 
    Y
FROM dbo.A

    LEFT OUTER JOIN dbo.B
        ON dbo.A.X = dbo.b.X

WHERE dbo.B.X IS NULL
AND Z <=0

これは、コードのFETCH NEXT FROM部分でパフォーマンスの問題として現れるとは思いませんが、まだカフェインを注入していません。私の提案を試してみて、私に知らせてください。

お役に立てれば、

マット


4

インデックスを確認し、すべての統計を更新します。私は非常に似たような問題を抱えており、1台のマシンの統計が不安定であることが判明しました。


1

これと同じ動作を2回経験しましたが、毎回何が修正されたかを説明します。

1.)キャッシュプランがひどいため、ストアドプロシージャにWITH RECOMPILEヒントを追加しました。

2.)テーブル変数の代わりに一時テーブルを使用するようにストアドプロシージャを変更しました。

これらのいずれかが役立つことを願っています。幸運を。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.