我有一个有趣的情况。当我在Microsoft SQL Server Management Studio上对远程SQL服务器运行查询时,它运行得很快(12秒),但是当我使用
变量
这段代码会得到相同时间的结果。
DbContext.Database.SqlQuery<EntityType>(script)
在Entity Framework中运行相同的查询时,需要48秒。 我尝试了设置set arithabort on
。该设置已应用,但未改变性能。我无法提供查询执行计划,因为我在SQL服务器上只有有限的权限。 但我可以百分之百地说,这不是查询问题。考虑以下查询:declare @t table (...)
insert into @t
select <long query>
select top 1 * from @t
变量
@t
包含约35k行。在EF和SSMS中,执行时间基本相同。但是当我删除top 1
时,奇怪的事情开始发生。在SSMS中,我需要10秒钟,但在EF中需要大约40秒。
我想这个小实验可以排除SQL Server选择错误的执行计划并放慢事物的可能性。
另一个有趣的点是由EF完成的实体材料化。我认为这也不是瓶颈,因为当我在本地SQL Express上运行类似查询并获得类似大小的结果集时,在两种情况下我几乎立即得到了结果。
所以我的下一个猜测是网络问题。我安装了Microsoft Network Monitor 3.4,并监视了SSMS和EF的网络流量。我发现有趣的事情是由于某种原因,EF版本有许多较小的数据包和一些TLS数据包。在SSMS版本中,数据包大小更加稳定,而且没有TLS数据包。
那么问题是:是否可能加速EF版本?那些TLS包是什么,是否可能摆脱它们?
更新
Entity Framework v6.1.3
.NET v4.5.1
SQL Server v10.50.2550.0
本地SQLExpress v12.0.4213.0
Windows 7 Pro
更新
using (var connection = new SqlConnection(DbContext.Database.Connection.ConnectionString))
using (var cmd = new SqlCommand(script, connection))
{
connection.Open();
cmd.CommandType = CommandType.Text;
using (SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
do
{
} while (reader.Read());
}
}
这段代码会得到相同时间的结果。