強力なサーバーでSQL Server 2014を実行している約1 TBの大規模データベースがあります。数年はすべてうまくいきました。約2週間前に、次のような完全なメンテナンスを行いました。すべてのソフトウェアアップデートをインストールします。すべてのインデックスを再構築し、DBファイルを圧縮します。ただし、実際の負荷が同じ場合、特定の段階でDBのCPU使用率が100%から150%増加するとは予想していませんでした。
多くのトラブルシューティングを行った後、非常に単純なクエリに絞り込みましたが、解決策が見つかりませんでした。クエリは非常に簡単です。
select top 1 EventID from EventLog with (nolock) order by EventID
常に約1.5秒かかります!ただし、「desc」を使用した同様のクエリには常に約0ミリ秒かかります。
select top 1 EventID from EventLog with (nolock) order by EventID desc
PTableには約5億行があります。データ型がbigint(Identity列)EventID
のプライマリクラスター化インデックス列(ordered ASC
)です。上部のテーブルにデータを挿入する複数のスレッド(より大きなEventID)があり、下部からデータを削除する1つのスレッド(より小さなEventID)があります。
SMSSでは、2つのクエリが常に同じ実行プランを使用することを確認しました。
クラスター化インデックススキャン。
推定および実際の行番号は両方とも1です。
推定および実際の実行回数は両方とも1です。
推定I / Oコストは8500です(高いようです)
連続して実行した場合、クエリコストは両方で同じ50%です。
インデックス統計を更新しましたがwith fullscan
、問題は続きました。インデックスを再構築しましたが、問題は半日消えたようですが、戻ってきました。
IO統計をオンにしました:
set statistics io on
次に、2つのクエリを連続して実行し、次の情報を見つけました。
(最初のクエリについては、遅いクエリ)
テーブル「PTable」。スキャンカウント1、論理読み取り407670、物理読み取り0、先読み読み取り0、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0。
(2番目のクエリ、高速クエリの場合)
テーブル「PTable」。スキャンカウント1、論理読み取り4、物理読み取り0、先読み読み取り0、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0
論理読み取りの大きな違いに注意してください。両方の場合にインデックスが使用されます。
インデックスの断片化は少し説明できますが、その影響は非常に小さいと思います。そして、問題は以前に一度も起こりませんでした。別の証拠は、次のようなクエリを実行した場合です。
select * from EventLog with (nolock) where EventID=xxxx
xxxxをテーブル内の最小のEventIDに設定しても、クエリは常に高速です。
チェックしましたが、ロック/ブロックの問題はありません。
注:上記の問題を単純化しようとしました。「PTable」は実際には「EventLog」です。PID
ですEventID
。
NOLOCK
ヒントなしで同じ結果をテストできます。
誰でも助けることができますか?
XMLでのより詳細なクエリ実行計画は次のとおりです。
https://www.brentozar.com/pastetheplan/?id=SJ3eiVnob
https://www.brentozar.com/pastetheplan/?id=r1rOjVhoZ
create tableステートメントを提供することは重要ではないと思います。これは古いデータベースであり、メンテナンスまで長い間完全に正常に実行されています。私たちは多くの調査を自分で行い、質問で提供された情報に絞り込みました。
テーブルは通常、EventID
列を主キーとして作成され、これはidentity
typeの列ですbigint
。現時点では、問題はインデックスの断片化にあると思います。インデックスの再構築直後、問題は半日はなくなったようです。しかし、なぜそれがそんなに早く戻ってきたのか...?