实体框架数据读取性能

7
我有一个有趣的情况。当我在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包是什么,是否可能摆脱它们?

SSMS traffic EF traffic

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

这段代码会得到相同时间的结果。
1个回答

4

我做了一些研究和实验,发现在连接字符串中添加packet size=32768(这是最大尺寸)选项似乎能将速度提高到几乎与SSMS相同的水平。有趣的是,我收到的TCP数据包并没有增加大小。

我也尝试过其他连接字符串选项,但没有注意到任何明显的速度提升。


在此处找到WAN连接的类似情况。平均数据包大小未改变(约为1400),但吞吐量从550kBs增加到1800kBs。SSMS也达到了约1800kBs。使用NetworkTrafficView(NirSoft)。 - crokusek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接