我们有一个使用linq实体的网站,我们发现它最近很慢,经过故障排除后,我发现每当我们使用linq实体从数据库中搜索数据时,它会消耗很多CPU时间,比如{{ 1}}功能。我知道这可能是因为我们在数据库中有大量数据会导致响应变慢,但我只是想知道是否还有其他可能导致此问题的原因?
如何优化这些问题呢?以下是可能的原因:
toList()
可能会加载所有对象的外来对象(外键),如何强制它只加载对象?
我的连接池太小了吗?
如果还有其他可能的原因,请告诉我,并指出正确的方向来解决这个问题。
答案 0 :(得分:5)
在Linq中 - 查询会在枚举查询时将一系列操作的结果返回到 。
IQueryable<Customer> myQuery = ...
foreach(Customer c in myQuery) //enumerating the query causes it to be executed
{
}
List<Customer> customers = myQuery.ToList();
// ToList will enumerate the query, and put the results in a list.
// enumerating the query causes it to be executed.
执行查询需要一些事情(没有特别的顺序)
此外,数据库有几个步骤,这里是从查询sql server的角度列出的:
所以 - 要找出查询问题的位置,您需要开始测量。我会按照我检查的顺序订购这些目标。这不是一个完整的清单。
获取查询的已翻译sql文本。您可以使用sql server profiler。您可以使用调试器。有很多方法可以解决这个问题。确保查询文本返回对象所需的内容,不多也不少。确保查询的表符合您的期望。运行查询几次。
查看结果集。这是合理的还是我们正在寻找500 Gigs的结果?当整个事情不需要时,是否会查询整个表格?是否意外地产生了笛卡尔结果?
获取查询的执行计划(在sql studio中,单击show estimated execution plan
按钮)。查询是否使用您期望的索引?该计划看起来很糟糕(可能是一个糟糕的计划来自缓存)?查询是否按照您期望的顺序在表上工作,并以您期望的方式执行嵌套/合并/散列连接?是否存在并行化,当查询不值得时(这是错误索引的标志/ IO的TONS)?
测量查询的IO。 (在sql server中,发出SET STATISTICS IO ON)。检查每个表的逻辑IO。哪张桌子突出?再次,查找表访问的错误顺序或可以支持查询的索引。
如果你已经做到这一点,你很可能找到并修复了问题。我会坚持下去,万一你还没有。
将查询的执行时间与枚举的执行时间进行比较。如果存在很大差异,则可能是解释数据对象的代码很慢或生成缓慢。也可能是查询的翻译需要一段时间。这些都是棘手的问题需要解决(在LinqToSql中我们使用编译的查询对它们进行排序)。
测量代码运行的机器的内存和CPU。如果您受限,请使用代码分析器或内存分析器来识别并解决问题。
查看计算机上的网络统计信息,特别是您可能希望使用TCPView查看计算机上的TCP套接字连接。套接字资源可能被误用(例如在一分钟内打开和关闭数千个)。
检查数据库是否有其他连接所持有的锁。
我想这就够了。希望我没有忘记任何明显的事情要检查。
答案 1 :(得分:0)
您可以在MSDN上的Performance Considerations (Entity Framework)中找到问题的解决方案。特别是
返回正确的数据量
在某些情况下,使用Include方法指定查询路径是 更快,因为它需要更少的往返数据库。 但是,在其他情况下,额外往返数据库往返 加载相关对象可能会更快,因为更简单的查询 连接越少,数据冗余越少。因此,我们 建议您测试各种检索方式的性能 相关对象。有关详细信息,请参阅Loading Related Objects。
为避免在单个查询中返回过多数据,请考虑分页 查询到更易管理的组的结果。更多 信息,请参阅How to: Page Through Query Results。