从静态列表中查询对象会导致服务器上的CPU使用率出现峰值

时间:2012-01-08 10:16:27

标签: c# asp.net list collections

我们有一个类似于SO上的相关问题的功能,我们在查看给定记录时显示相关记录。每次加载页面时都通过调用db来检索相关记录。为了减少db上的负载,我在Application_Start上加载了这些记录的静态List,现在使用Linq查询来查询此List。

在大多数情况下,这似乎工作正常。 db上的负载减少了,Sql profiler显示没有更多的相关记录查询。昨晚我推动了这个改变,今天早上我发现IIS工作进程的CPU处于100%且网站没有响应。我切换回旧代码(我查询数据库),Web服务器上的东西很好但数据库负载增加了。所以我再次切换到新代码并一直在查看Web服务器上的cpu负载。这就是我注意到的。

当使用查询db的旧代码时,IIS Worker进程的cpu使用率可以忽略不计,并且几乎没有任何变化(在任务管理器的性能选项卡中看到直线)但是,当使用创建的新代码时并查询静态列表,我看到IIS工作进程的CPU使用率出现高峰。大多数情况下,它介于1%和5%之间,但是它时不时地超过了它,自从我开始观察以来,我看到的最大值是40%。我想知道为什么会发生这种情况,是否在负载很重的情况下,这可能会导致工作进程崩溃?

以下是一些查询静态列表的代码

    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();
        }

List支持多个并发读取器,因此StaticRecords不应该是阻塞因素。之后我创建了filteredRecords,这是一个新的过滤列表,应该独立于其他线程。

可能是CPU出现高峰的可能原因,是否会导致IIS工作进程早期崩溃?

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

我现在知道崩溃不是由于这个代码造成的,而是另一个错误。静态列表方法一直很稳定,似乎已经很好地实现了它的目的。

但我的问题仍然存在,为什么CPU出现高峰?

当我说

  

List支持多个并发读取器,因此StaticRecords不应该   是阻碍因素。之后我创建了filteredRecords   这是一个新的过滤列表,应该独立于其他列表   线程。

我错了吗?

2 个答案:

答案 0 :(得分:3)

SQL Server通常在查询时非常有效,尤其是在您正确优化索引时。

您的新StaticRecords方法需要对所有项目进行内存中扫描,并为每个项目执行Where谓词。这可能是导致CPU使用率增加的原因,尤其是StaticRecords中有很多项目时。尝试附加一个分析器并亲自看看。一般来说,我希望这种过滤在SQL Server上运行和内存过滤时能够更好地执行数量级。

答案 1 :(得分:1)

性能问题可能是由于扫描了List中的StaticRecords

将数据读入内存一次很好,但看起来你需要一个更有效的数据结构才能有效地查询它。您可能还想重新考虑使用LINQ进行查询。

至于导致崩溃和100%CPU峰值的原因,我发现您发布的代码中没有明显错误。