猿问

在连接关闭之前查询完成后实体框架挂起

我正在尝试提高相对复杂的实体框架查询的性能。使用DbContext.Database.Log我在执行我感兴趣的主要查询时检查输出的操作,我发现了一些奇怪的东西。根据日志,查询本身只需要大约 10,000 毫秒,但是在查询“完成”和连接关闭之间有超过一分钟的时间。我不知道这次发生了什么,因为日志显示一个空白行。这是输出:

2018-09-07 14:10:34,641 [1] INFO EntityDataRepository [jobInstanceID: 0] - -- 执行于 2018 年 9 月 7 日下午 2:10:34 -07:00

2018-09-07 14:10:46,421 [1] INFO EntityDataRepository [jobInstanceID: 0] - -- 在 11776 毫秒内完成,结果:SqlDataReader

2018-09-07 14:10:46,458 [1] INFO EntityDataRepository [jobInstanceID: 0] -

2018-09-07 14:11:48,667 [1] INFO EntityDataRepository [jobInstanceID: 0] - 2018 年 9 月 7 日下午 2:11:48 -07:00 关闭连接

有人可以告诉我这里发生了什么吗?请参阅下面的代码的简化/通用版本:

(from child in entities.SelectMany(e => e.children.Where(childFilter))

join read in childReads on child.ID equals read.childID

join readType in readTypes on read.readTypeID equals readType.ID

where readFilter

select new {child, read, readType}).ToList()


绝地无双
浏览 155回答 1
1回答

catspeake

2018-09-07 14:10:46,421&nbsp;1&nbsp;INFO EntityDataRepository [jobInstanceID: 0] - -- 在 11776 毫秒内完成,结果:SqlDataReader这意味着SqlCommand.ExecuteReader()已经完成,服务器开始向客户端返回行。SQL Sever 中的查询此时仍在执行。它可能已经假脱机了所有查询结果,或者它可能刚刚使用流式查询计划找到并返回了前几个匹配的行。因此,IQueryable<T>.ToList()要完成,查询需要在服务器上完成执行,结果行必须传输到客户端,EF 必须读取行并将它们具体化为 type 的类实例T。可以使用Visual Studio Profiler、性能计数器或System.Diagnostics.Process分析客户端工作。SQL Server 跟踪计划缓存中查询的查询执行统计信息,如果在 SQL 2016+ 中使用查询存储,则跟踪所有查询。统计信息将向您显示查询经过的时间,其中包括等待客户端读取(和处理)行和所有其他等待的时间,以及“工作时间”,即查询使用的 CPU 时间。SQL 2017 和 Azure SQL 数据库中的查询存储还跟踪每个查询的等待统计信息,因此您可以区分客户端ASYNC_NETWORK_IO等待(&nbsp;) 和其他等待,如数据文件读取 (&nbsp;PAGEIOLATCH)、锁定等待 (&nbsp;LCK_*_*) 等。
随时随地看视频慕课网APP
我要回答