为什么在 .toList() in linq to entities.

本文关键字:linq to entities in toList 为什么 | 更新日期: 2023-09-27 18:34:28

我们有一个网站正在使用linq to entities,我们发现最近它很慢,经过故障排除,我发现每当我们使用linq to entity从数据库中搜索数据时,它都会消耗非常多的CPU时间,就像toList()函数一样。 我知道这可能是因为我们数据库中有很多数据导致响应缓慢,但我只是想知道是否有任何其他原因可能导致此问题?

我应该如何优化这类问题? 以下是可能的原因:

  1. ToList()可能会加载所有对象的外部对象(外键(,如何强制它只加载对象?

  2. 我的连接池是否太小?

如果有任何其他可能的原因,请告诉我,并为我指出解决此问题的正确方向。

为什么在 .toList() in linq to entities.

在 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.

执行查询需要一些东西(排名不分先后(

  • 从池中提取数据库连接。
  • 查询
  • 由查询提供程序解释(在这种情况下,提供程序对实体是 linq,解释是某种形式的 sql(
  • 解释后的形式被传输到数据库,在那里它执行它所做的事情并返回数据对象。
  • 必须生成一些方法才能将传入的数据对象转换为所需的查询输出。
  • 数据库连接将返回到池中。
  • 在将所需的查询输出返回到代码之前,可能需要对其进行状态跟踪。

此外,数据库还有几个步骤,这里从查询 sql 服务器的角度列出了这些步骤:

  • 接收查询文本,并根据现有计划的查询计划缓存进行检查。
  • 如果不存在计划,则查询优化器将创建一个新计划并将其粘贴到计划缓存中。
  • 执行查询计划 - IO/锁/CPU/内存 - 其中任何一个都可能是瓶颈
  • 返回查询结果 - 网络可能是一个瓶颈,尤其是在结果集很大的情况下。

所以 - 要找出查询的问题在哪里,你需要开始测量。 我将按照检查它们的顺序对这些目标进行排序。 这不是一个完整的列表。

  1. 获取查询的已翻译 sql 文本。 为此,可以使用 SQL 服务器事件探查器。 可以使用调试器。 有很多方法可以做到这一点。 确保查询文本返回对象所需的内容,不多也不少。 确保查询的表符合您的期望。 运行查询几次。

  2. 查看结果集。 这是否合理,或者我们是否在查看 500 Gigs 的结果? 当不需要整个事情时,是否查询了整个桌子? 笛卡尔结果是意外生成的吗?

  3. 获取查询的执行计划(在 sql Studio 中,单击"show estimated execution plan"按钮(。 查询是否使用您期望的索引? 计划看起来很奇怪(可能是来自缓存的糟糕计划(? 查询是否按预期顺序处理表,并按预期方式执行嵌套/合并/哈希联接? 当查询不值得时,是否有并行化开始(这是错误索引/吨 IO 的迹象(?

  4. 测量查询的 IO。(在 SQL SERVER 中,问题"将统计信息 IO 设置为打开"(。 检查每个表的逻辑 IO。 哪张桌子脱颖而出? 同样,查找错误的表访问顺序或可以支持查询的索引。

    如果您已经做到了这一点,您可能已经发现并解决了问题。 不过我会继续前进,以防你还没有。

  5. 将查询的执行时间
  6. 与枚举的执行时间进行比较。 如果存在很大差异,则可能是解释数据对象的代码很慢或生成速度很慢。 也可能是查询的翻译需要一段时间。 这些都是难以解决的问题(在 LinqToSql 中,我们使用编译的查询来整理它们(。

  7. 测量运行代码的计算机的内存和 CPU。 如果限制在那里,请使用代码探查器或内存探查器来识别和解决问题。

  8. 查看计算机上的网络统计信息,特别是您可能希望使用 TCPView 查看计算机上的 TCP 套接字连接。 套接字资源可能被滥用(例如在一分钟内打开和关闭数千个套接字资源(。

  9. 检查数据库中是否有其他连接持有的锁。

我想这就够了。 希望我没有忘记任何明显的事情要检查。

您可能会在 MSDN 上的性能注意事项(实体框架(中找到问题的解决方案。特别

返回正确的数据量

在某些情况下,使用 Include 方法指定查询路径是 速度要快得多,因为它需要更少的数据库往返次数。 但是,在其他情况下,到数据库的额外往返 加载相关对象可能会更快,因为查询越简单 联接越少,数据冗余越少。正因为如此,我们 建议您测试各种检索方式的性能 相关对象。有关更多信息,请参见加载相关对象。

若要避免在单个查询中返回太多数据,请考虑分页 将查询结果放入更易于管理的组中。欲了解更多信息 信息,请参见如何:逐页浏览查询结果。