2012-01-08 11 views
4

特定のレコードを表示しているときに関連するレコードを表示する関連する質問と同様の機能があります。関連するレコードは、ページがロードされるたびにdbを呼び出すことによって取得されていました。 dbの負荷を軽減するために、私はApplication_Startにロードするこれらのレコードの静的Listを作成しました.Lineqクエリを使用してこのリストをクエリしています。静的リストからオブジェクトを照会サーバー上のCPU使用率が急上昇している

ほとんどの場合、これはうまくいくようです。 dbの負荷が軽減され、SQLプロファイラに関連するレコードクエリがないことが示されます。私は昨晩この変更を進めていましたが、今朝私はIISワーカープロセスがCPUを100%にし、Webサイトが応答しないことがわかりました。私は以前のコードに戻って(私はdbを照会する)、物事はウェブサーバー上であったが、データベースの負荷が増加した。そこで私は新しいコードに再度切り替え、WebサーバーのCPU負荷を調べています。これは私が気づいたものです。

dbをクエリする古いコードを使用すると、IIS WorkerプロセスのCPU使用率はごくわずかであり、バリエーションはほとんどありません(タスクマネージャの[パフォーマンス]タブに直線が表示されます)。静的Listを作成してクエリを実行すると、IISワーカープロセスのCPU使用率が急上昇しています。ほとんどそれは1から5%の間ですが、今はそれ以上のスパイクがあり、私が見てきた最大値は観測を開始してから40%です。私はなぜこれが起こっているのだろうと重い負荷の下で、これはワーカープロセスがクラッシュする可能性があるかどうか疑問に思っていますか?ここ

StaticRecordsはブロッキング因子であってはならないので、静的リストを

if (validSearchLatLong && (usePincodeLatLong || distanceFilterLimit != distanceLimit)) 
     { 
      filteredRecords = StaticRecords.Where(job => LatLongDistance(centerLatitude, centerLongitude, job.lat, job.lon) <= distanceFilterLimit || (!string.IsNullOrEmpty(this.PreferredJobCity) ? job.city == this.PreferredJobCity : false)).ToList(); 
     } 
     else 
     { 
      filteredRecords = StaticRecords.Where(job => (this.PreferredJobCity != "" ? job.city == this.PreferredJobCity : (this.City != "" ? job.city == this.city : (state != "" ? job.state.Trim() == state.Trim() : false)))).ToList(); 
     } 

     if (RecordsearchFilter.JobCategories.Count > 0 && RecordsearchFilter.EnableFilter) 
     { 
      filteredRecords = filteredRecords.Where(job => this.RecordsearchFilter.JobCategories.Contains(job.JobCategoryClass)).ToList(); 
     } 
     else 
     { 
      filteredRecords = filteredRecords.Where(job => MatchJobCategories(job.JobCategory, (short)this.jobCategory.SqlId) > 0).ToList(); 
     } 

リストを照会されたコードの一部は、複数の同時リーダーをサポートしています。そしてその後、私はfilteredRecordsを作成しています。これは、他のスレッドから独立しているはずの新しいフィルターリストです。

CPUのスパイクの原因として、IISワーカープロセスの以前のクラッシュが発生した可能性があります。

============ EDIT ==============

私は今のクラッシュが原因このコードに発生していないことを知っているが、別のバグ。静的Listアプローチは安定しており、その目的を達成するうえでうまくいっているようです。

しかし、私の質問はまだ残っています、なぜCPUのスパイクですか? StaticRecordsが はブロッキング係数ではありませんので

私は

一覧を言って、同時に複数のリーダをサポートしています。そしてその後、私はfilteredRecords を作成しています。これは、他の スレッドとは独立したフィルタリングされた新しいリストです。

私は間違っていますか?

+0

トレースをオンにしてメソッド呼び出しの時間を表示しましたか? – Lloyd

+0

静的レコードはどれくらい大きいですか?あなたはスパイク中にpagefaultsを見ていますか? StaticRecordsはリストを使用していますか? – rene

+0

@reneはいStaticRecordsはリストを使用します。それは約35000のレコードを持っています。 asp.netページでエラーが発生した場合はpagefaults、そうでない場合はまだ見ていません。 – shashi

答えて

3

通常、インデックスを最適化すると、特にSQL Serverのクエリが非常に効率的です。

新しいStaticRecordsアプローチでは、すべてのアイテムのメモリ内スキャンが必要で、それぞれにWhere述語を実行する必要があります。これは、特に多くのアイテムがStaticRecordsにある場合、CPU使用率を増やす原因になります。プロファイラをつけてみてください。一般に、SQL Serverとメモリ内のフィルタリングの両方で実行すると、このようなフィルタリングの方がはるかに優れたパフォーマンスが期待できます。

+0

WebサーバでのCPU使用率の増加は予想され、一貫している限り(ほとんど1〜5%の間)、問題ありません。私が心配している使用法のスパイクです(40%に達すると)。なぜ突然のスパイクが見られるのですか? SQL Serverを使用する場合、メモリ内のアプローチはSqlサーバーの負荷を軽減することです。問題の特定のクエリが最適化され、必要なインデックスがすべて整備されています。私はdbエンドでさらに最適化が可能でなければならないと確信していますが、解決策を思いつくうちにサイトをダウンさせることはできません。これは速い修正のようなものです – shashi

+0

結果をキャッシュすると考えましたか?スパイクは、そのコードを打ついくつかの同時リクエストのような単純な原因を持つかもしれません。 – driis

1

パフォーマンスの問題は、おそらくStaticRecordsListをスキャンによるものです。メモリにデータを読み込み

一度罰金ですが、あなたはそれを効果的に照会するために、より効率的なデータ構造を必要とするように見えます。また、LINQを使用してクエリを実行するという考え方に戻ってみることもできます。

限り、何があなたのクラッシュ、100%のCPUスパイクを引き起こしたとして、私はあなたが投稿したコードの明らかなエラーが表示されません。

+0

Linqの代わりに何をお勧めしますか?上記の2つのフィルタとは別に、さらに多くのフィルタがあります。この手法は、第1のフィルタが多くのリストを減らし、次にfilteredRecordsを次のフィルタに渡し、それから少数のフィルタについてさらに減少させ、同じことを繰り返すようなやり方である。現在、staticListには約35000個のオブジェクトが含まれており、最初のフィルタの後に結果は約5000個のオブジェクトになります。次のフィルタは、35000ではなく5000個のオブジェクトに適用されます。したがって、正常に動作します。私は突然のスパイクについて心配しています。クラッシュの原因となる可能性があります。 – shashi

+0

LINQの使用 - Application_Startでは使用しないでください。代わりに、必要なときにモデルにクエリを実行しますが、クエリをキャッシュします(たとえば、キャッシュキーにパラメータの区切りリストを作成します) – TheGeekYouNeed

関連する問題