私の会社では、かなり大きなパフォーマンスの問題があるアプリケーションを使用しています。データベース自体には多くの問題がありますが、私が取り組んでいるところですが、問題の多くは純粋にアプリケーションに関連しています。
私の調査では、空のテーブルをクエリする何百万ものクエリがSQL Serverデータベースにヒットしていることがわかりました。約300の空のテーブルがあり、それらのテーブルの一部は1分あたり最大100〜200回クエリされます。テーブルは私たちのビジネス領域とは何の関係もなく、基本的に元のアプリケーションの一部であり、ベンダーが私たちのためにソフトウェアソリューションを作成するように契約したときにベンダーが削除しませんでした。
アプリケーションエラーログがこの問題に関連するエラーであふれていると思われるという事実は別として、ベンダーは、アプリケーションまたはデータベースサーバーのいずれにもパフォーマンスまたは安定性の影響がないことを保証します。エラーログは、診断を行うために2分を超える価値のあるエラーが表示されない程度にフラッディングされます。
これらのクエリの実際のコストは、CPUサイクルなどの点で明らかに低くなります。しかし、SQL Serverとアプリケーションにどのような影響があるかを誰かが示唆できますか?リクエストの送信、確認、処理、返送、アプリケーションによる受信確認の実際のメカニズム自体がパフォーマンスに影響を与えると思います。
アプリにはSQL Server 2008 R2、Oracle Weblogic 11gを使用しています。
@ Frisbee-短い話ですが、アプリのデータベースの空のテーブルにヒットするクエリテキストを含むテーブルを作成し、空であることがわかっているすべてのテーブル名についてクエリを実行し、非常に長いリストを取得しました。トップヒットは30日間の稼働時間で270万回の実行でした。アプリは一般的に午前8時から午後6時まで使用されているため、これらの数値は運用時間に集中しています。複数のテーブル、複数のクエリ、おそらく結合を介した関連性の高いものとそうでないもの。トップヒット(当時は270万)は、結合のないwhere句を使用した単一の空のテーブルからの単純な選択でした。空のテーブルへの結合を伴うより大きなクエリにはリンクテーブルの更新が含まれる可能性があると予想しますが、それを確認してこの質問をできるだけ早く更新します。
更新:1043から4622614(2.5か月以上)の実行数のクエリが1000個あります。キャッシュされたプランがいつから始まったかを調べるために、さらに掘り下げる必要があります。これは、クエリの範囲を把握するためのものです。ほとんどは、20を超える結合でかなり複雑です。
@ srutzky-はい、計画がいつコンパイルされたかに関連する日付列があると思いますので、それを確認してみましょう。SQL ServerがVMwareクラスター上にある場合、スレッドの制限が要因になるのでしょうか。ありがたいことに、すぐに専用のDell PE 730xDになります。
@Frisbee-返信が遅くなってすみません。あなたが示唆したように、SQLQueryStress(実際には240,000回の反復)を使用して、空のテーブルからselect *を24スレッドで10,000回実行し、10,000バッチリクエスト/秒をすぐにヒットしました。その後、24スレッドで1000倍に削減し、4,000バッチリクエスト/秒未満でヒットしました。また、12スレッドのみで10,000回の反復を試行し(合計120000回の反復)、これにより、持続的な6,505バッチ/秒が生成されました。CPUへの影響は実際に顕著で、各テスト実行中の合計CPU使用量の約5〜10%です。ネットワーク待機はごくわずかでした(私のワークステーション上のクライアントで3ミリ秒など)が、CPUへの影響は確かにありました。それは、CPU使用率と、不要なデータベースファイルIOに要約されます。1秒あたりの合計実行回数は3000弱で計算され、これは本番環境ではありませんが、このような数十のクエリの1つだけをテストしています。したがって、毎分300〜4000回の割合で空のテーブルにヒットする何百ものクエリの正味の影響は、CPU時間に関しては無視できません。すべてのテストは、デュアルフラッシュアレイと256GB RAM、12個の最新コアを備えたアイドル状態のPE 730xDに対して行われました。
@ srutzky-良い考え。SQLQueryStressはデフォルトで接続プールを使用しているようですが、とにかく調べてみたところ、接続プールのボックスがオンになっていることがわかりました。フォローして更新
@ srutzky-アプリケーションで接続プーリングが有効になっていないようです-有効になっている場合は機能していません。プロファイラートレースを実行したところ、接続に監査ログインイベント用のEventSubClass "1-Nonpooled"があることがわかりました。
RE:接続プーリング-weblogicsをチェックしたところ、有効な接続プーリングが見つかりました。プーリングのトレースをさらに実行し、プーリングの兆候が正しく/まったく発生していないことを発見しました:
次に、データが設定されたテーブルに対して結合を使用せずに単一のクエリを実行すると、次のようになります。例外は、「SQL Serverへの接続の確立中にネットワーク関連またはインスタンス固有のエラーが発生しました。サーバーが見つからなかったか、アクセスできませんでした。インスタンス名が正しく、SQL Serverがリモート接続を許可するように構成されていることを確認してください。 (プロバイダー:名前付きパイププロバイダー、エラー:40-SQL Serverへの接続を開けませんでした) "バッチリクエストカウンターに注意してください。例外が生成されている間にサーバーにpingを実行すると、ping応答が成功します。
更新-2つの連続するテスト実行、同じワークロード(select * fromEmptyTable)、プーリング有効/無効。CPU使用率がやや多く、多くの障害が発生し、500バッチリクエスト/秒を超えることはありません。テストでは、10,000バッチ/秒でプールがオンの場合の障害はなく、約400バッチ/秒の場合、プールが無効になっているために多くの障害が発生しています。これらの失敗は接続の可用性の欠如に関連しているのだろうか?
@ srutzky- sys.dm_exec_connectionsからCount(*)を選択します。
プーリングが有効:負荷テストが停止した後でも37が一貫して
無効化されたプーリング:
SQLQueryStressで例外が発生しているかどうかに応じて11-37。つまり、これらの谷がBatches
/ secグラフに表示されると、SQLQueryStressで例外が発生し
、接続数が11に減少し、その後37に徐々に戻ります。バッチがピークに達し、例外が発生していないとき。とても面白いです
デフォルトの0に設定されている両方のテスト/ライブインスタンスの最大接続数。
アプリケーションログを確認しても接続の問題は見つかりませんが、エラーの数とサイズが多いため、利用できるログ記録は数分しかありません。つまり、スタックトレースエラーがたくさんあります。アプリサポートの同僚は、接続に関連してかなりの数のHTTPエラーが発生するとアドバイスしています。これは、何らかの理由でアプリケーションが正しく接続をプールしておらず、その結果、サーバーが繰り返し接続を使い果たしているように思われます。アプリのログを詳しく調べます。これがSQL Server側からの運用で起こっていることを証明する方法はあるのでしょうか。
@ srutzky-ありがとうございます。明日weblogicの設定を確認して更新します。たった37の接続について考えていましたが、SQLQueryStressが12のスレッドを10,000回の反復で実行している場合= 120,000の選択ステートメントがプールされていない場合、各選択がSQLインスタンスへの個別の接続を作成することを意味しませんか?
@ srutzky- Weblogicは接続をプールするように構成されているため、正常に機能しているはずです。接続プーリングは、4つの負荷分散された各Weblogicで次のように構成されます。
- 初期容量:10
- 最大収容人数:50
- 最小容量:5
空のテーブルからの選択クエリを実行するスレッドの数を増やすと、接続数は最大で約47になります。接続プーリングが無効になっていると、毎秒の最大バッチ要求が常に低くなっています(10,000から約400に)。毎回発生するのは、SQLQueryStressの「例外」が、バッチ/秒が谷に入った直後に発生することです。これは接続性に関連していますが、なぜこれが起こっているのか正確には理解できません。テストが実行されていない場合、#connectionsは約12に下がります。
接続プーリングが無効になっていると、例外が発生する理由を理解できませんが、それがAdam Machanicに対する他のstackExchange質問/質問である可能性がありますか?
@srutzky SQL Serverの接続が不足していなくても、プーリングを有効にせずに例外が発生するのはなぜでしょうか。
SELECT COUNT(*) FROM sys.dm_exec_connections;
場合は、a を実行して、プールが有効な場合と無効な場合で値が大きく異なるかどうかを確認しますない。これらのエラーに基づいて、プーリングが無効になっている場合、接続はさらに多くなると思います。
Pooling=false
かMax Pool Size
?