この問題は、SQLサーバーとアプリケーション層の間の相互作用に関連していると思われます。あなたはそれについて言及していないので、あなたはあなたのアプリケーションでAPMを使用していないと仮定します。言うまでもなく、ほとんどの人の考えでは、APMはUIをより高速に動作させるためのものですよね?
サイエンスビット、コンセントレート
ASP.Net/IISは、デフォルトで限られた数のスレッドを提供します。スレッドは高価であることを忘れないでください。各スレッドはスケジューラーの時間を消費し、さまざまなスタックの形でメモリを消費します。これは、世界中のすべてのコンピューターのほとんどの欠陥です。
.netでは、すべての作業はスレッドで行われます。したがって、空きスレッドがない場合、IISはスレッドを待機するために要求をキューに入れます。さて、通常、すべてのスレッドが使用されていると、CPU使用率が高くなると思います。これは間違っています。一般に、最近のCPUでは、ほとんどの場合I / Oが不足しています。つまり、スリープ状態です。
この場合、一般的に発生するのは、いくつかのリクエストが入ってくることです。それぞれのスレッドがキックされ、データベースにアクセスします。それから彼らは待つ(眠る)。すべてのスレッドが使用されている間、CPU utilは0%に達します。より多くのリクエストが届きます。それらはキューに入れられます。データベース要求が返され、一部の要求がデキューされます(すべてではありません)。その後、キューのリクエストがタイムアウトします。
モアスレッド!
この問題をどのように解決しますか?明らかに、IISキューからできるだけ早く、SQLサーバーに多くの作業を移したいと思っています。ですから、明らかに答えはスレッドの数を増やすことですよね?さて、前述したように、スレッドは高価であるため、非常に強力なSQLサーバーを使用している場合、アプリケーションサーバーはSQLサーバーよりもかなり前にゴーストを放棄しますが、CPU使用率は0%です。明らかに、スレッドが増えると、目的の場所に到達できなくなります。
非同期/マジックソース待ち!
受け入れられている解決策は、実際に非同期プログラミングを使用することです。
しかし、UIと並列化を非同期/待機していませんか?
いいえ。ゲインを視覚化するのが最も簡単な場所であるため、UIと並列化で最も頻繁に示されます。1時間のデモで100万ヒット/秒のサービスをモックアップするのははるかに困難です。
したがって、データベースにクエリを送信すると、結果でスリープする代わりに、スレッドはIISキューに戻って、次の顧客にサービスを提供します。結果が返されると、次に使用可能なスレッドが通知され、それが処理されます。
したがって、データベース呼び出しのasync / awaitを使用すると、CPU /ネットワークユーティリティを最大限に活用して、データベースへの遅延を無視できます。実際、ボトルネックをSQLサーバーに移すべきだったことがわかります。
しかし、私のAPIはどこにありますか?
ああ...ここに問題があります。Async/Awaitはかなり新しいものです。使用するには、VS2012と.net4.5(まあまあ)が必要です。また、ほとんどのデータベースAPIは、Async/Awaitを完全にはサポートしていません。
たとえば、Entity Framework、Microsoftの主力DBテクノロジは、EF 6.0 ALPHA(これを書いている時点)でのみ非同期/待機をサポートし、ほとんどの場合、MSSQLSERVERでのみサポートします。