事前に:質問の長さについて申し訳ありません...詳細と簡潔さの適切なバランスをとることができません。
WebアプリケーションのDBサーバーに問題があり、非常に短い時間(<10ms)で実行する必要がある(通常は実行する)クエリが、ランダムに実行に1〜30秒かかる場合があります。パターン。プロファイラーのトレースによると、"exec sp_reset_connection"
(通常は0ミリ秒で実行され、3〜6秒のピークが観測されます)や"SET NO_BROWSETABLE ON"
など、「何もしない」クエリでさえあります。いくつかの例は:
SELECT * FROM [Localisation].[TimeZoneRule] WHERE [Name] = 'EU'
ここで、TimeZoneRule
には5列に約500,000行あります。代理主キーとName
のインデックスがあります。通常は0.97ミリ秒かかり、ピークは11秒です。テーブルは決して書き込まれません(稼働前に事前入力されています)。プロファイラーは、0〜15 CPU、18〜25読み取り、0-1書き込み(書き込みの理由がわからない)を使用していると記録します。
UPDATE [Core].[User] SET [LastUsed] = GETUTCDATE() WHERE Id = '<uid>'
ここで、User
には約10列(そのうちの1つはXml列)に約30,000行あります。 Id
はクラスター化された主キーです。テーブルは定期的に書き込まれ、読み取られます。通常は10〜20msかかり、ピークは26秒です。プロファイラーは、CPUを0、読み取りを15-36、書き込みを0-1として記録します。
INSERT INTO [Log].[Session] (ASPSessionId, Start, ClientAddress, ClientSoftware, ProxyAddress, ProxySoftware)
VALUES(<number>, GETUTCDATE(), '<ipv4address>', '<User agent string>', '<ipv4address>', '<proxy software name (if present)>')
ここで、Session
には約8列にわたって約1,000,000行が含まれています。代理主キー(ID)と、ASPSessionId
のインデックスがあります。テーブルは定期的に書き込まれますが、読み取られることはめったにありません(SSMSから直接私たちだけが)。通常15〜150msかかり、5秒でピークになります。手元にプロファイルレコードはありませんが、メモリから見ると、CPUは約0で、読み取りと書き込みはそれぞれ0から100の間でした。
使用しているセットアップは、原則としてDell 2950(2つの4コアxeon 2.6、16Gb RAM)、およびミラーとしてDell 6850(4 HT Xeon 3.2、8Gb RAM)を使用したミラーリングセットアップです。どちらもSQL2005 SP464ビットを実行しています。問題のデータベースは特に大きくはなく、サイズは約16Gbです。プライマリには、6つのSASディスクが3つのRAID-1ボリュームに分割されています。1つはシステム+ページ+ TempDB用、1つはデータベースのMDF用、もう1つはトランザクションログ+時間ごとのログバックアップ+毎日のDB用です。バックアップ。ログの状況は、ディスクIO(以下を参照)およびデータセキュリティの観点から)最善とはほど遠いことを私は知っています。
これまでのところ、私たちは考える私たちは排除しました:
TimeZoneRule
に書き込まれることはなく、私の考えでは、排他ロックを設定することはできません。さらに、トレースを確認しましたが、多くの場合、実行されているのは「問題クエリ」だけです。他のアクティビティは、他の接続の切断だけです。(*)プロファイラーにロック取得に関連するイベントをキャプチャさせようとしましたが、トレースが読み取り不可能な比率に膨れ上がり、さらに悪いことに、Webアプリケーションが停止します。
DBAではないため、アイデアが急速に不足しています。誰かが私が次に見なければならないことや私が愚かに見逃したことを考えることができますか?
SQL 2005を実行しているときに、SQLプロファイラーデータを取得してPerfmonデータと比較し、相関関係を確認できるかどうかを確認できます。これは、通常の手法を使用してトレースデータとperfmonデータをファイルに保存することによって行われます。次に、プロファイラー内でSQLプロファイラートレースを開くと、ファイルメニューのオプションの1つが[パフォーマンスデータのインポート]になります。これにより、クエリを選択して、その時点でカウンターが何をしていたかを確認できます(または、perfmon収集間隔によってはそれに近いものになります)。
ディスクキューの急増は決して良いことではありません。特にその高さ。キューが高くなったときにディスクにプッシュしているIOは何ですか?基本的に、ディスク数が(2 * n)よりも大きいディスクキューは必要ありません。アレイ内。2ディスクRAIDを使用しているため1n = 1の場合(単一ディスクの速度しか得られないため)。
Perfmonには、読み取りあたりの秒数と書き込みあたりの秒数であるカウンターがあります。クエリの実行に時間がかかり始めると、これらのカウンターはどのようになりますか。通常はどうですか? (.02秒を超えるものはすべて悪いです。)推定ページ寿命はどれくらいですか? (通常、300秒未満のものはすべて不良ですが、これは異なる場合があります。)SQL Serverのキャッシュヒット率はどれくらいですか? (通常、97%未満のものはすべて悪いです。99.9%を超えるものが好きです。)
役に立たない、または役立つ可能性のあるものはほとんどありません。
これがストアドプロシージャで発生している場合は、パラメータスニッフィング-> http://omnibuzz-sql.blogspot.com/2006/11/parameter-sniffing-storedである可能性があります。 -procedures.html
WebアプリケーションにASPを使用していますか?同様の問題がありましたが、ASP + IISとストアドプロシージャを使用したSQL。これを引き起こすのはセマフォのタイムアウトだったことを覚えているようです。クエリの実行には30秒以上かかりますが、しばらくの間はすべて問題ありませんでした。それに関する情報ですが、それがIISタイムアウトに関連していることを覚えているようです、これはIIS側にありました。
このツールも役立つかもしれません-> http://blog.brianhartsock.com/2008/12/16/quick-and-dirty-sql-server-slow-query-log/
データベースのテーブルの統計を定期的に手動で再構築していますか?それらが古く、統計の自動更新オプションが設定されている場合、統計が再構築されている間、クエリは一時停止する可能性があります。
統計を手動で更新するだけでなく、非同期統計を有効にすることも検討できます。
これがT-SQLです:
ALTER DATABASE dbName SET AUTO_UPDATE_STATISTICS_ASYNC ON
参考文献:
http://msdn.Microsoft.com/en-us/library/ms190397.aspx
これが問題の根本原因であるとは確信していませんが、除外する価値があるかもしれません。
データベースおよび/または ログの増加 イベントが表示されていますか?このようなイベントは、ERRORLOGおよびパフォーマンスカウンターに表示されます。
試してみることがいくつかありますが、最も便利なのは、[推定実行プランの表示]と[SMSSに実際の実行プランを含める]です。
クエリを実行する前に[実際の実行プランを含める]ボタンにチェックマークを付けると、クエリが実行された後、クエリのコストがどこにあったかが表示されます。コストに基づいて、通常、どこで問題が発生したかを見つけるのは非常に簡単です。それがSORTの場合、それは悪いインデックスです。ハッシュテーブルを構築している場合、それは悪いインデックス/悪い結合です。単純なSELECT *クエリ中に発生することすら知らないかもしれない、うまくいかない可能性のあるあらゆる種類のことがあります。
2番目に試すことは、SQLクエリプロファイラーを実行することです(クエリを強調表示し、右クリックして、SQLプロファイラーでクエリをトレースします)。また、排除できる非効率性も見つかります。
ただし、クエリはすべて非常に単純であり、データベース設計の欠陥を示していません。ただし、少なくとも次に進むべき場所についてのアイデアが得られる可能性があります(明らかに、実行に予想よりも時間がかかるときに検査します)。 。
もう1つの場所は、情報過負荷の場合がありますが、SQL Serverプロファイラーです(既に使用したとおっしゃっていますが、26秒の実行中にそれをキャッチしましたか?)。 SQLサーバーが実行するすべてのことを(ほぼ)リアルタイムで監視できます。この種のアクティビティのウィンドウの長さに応じて、トレースを実行する準備ができている場合は、トレースを有効にし始めたらすぐに、SQLサーバーに待機しているものがあるかどうかを確認します。