我有一个有趣的情况。当我在Microsoft SQL Server Management Studio中的远程SQL服务器上运行查询时,它运行很快(12秒),但是当我在 Entity Framework 中使用DbContext.Database.SqlQuery<EntityType>(script)运行相同的查询时,则需要48秒。

我尝试设置set arithabort on。设置已应用,但没有改变性能。我无法提供查询执行计划,因为我对SQL Server的权限有限。但是我可以100%地说这不是查询问题。

考虑以下查询:

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数据包是什么,有可能摆脱它们吗?

c# -  Entity Framework 数据读取性能-LMLPHP
c# -  Entity Framework 数据读取性能-LMLPHP

更新
Entity Framework v6.1.3
.NET v4.5.1
SQL Server v10.50.2550.0
本地SQLExpress v12.0.4213.0
Windows 7专业版

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

此代码在时间上产生相同的结果。

最佳答案

我已经进行了一些研究和实验,似乎在连接字符串中添加packet size=32768(这是最大大小)选项趋向于将速度提高到几乎SSMS级别。有趣的是,我收到的TCP数据包而不是增加了它们的大小。

我也尝试了其他连接字符串选项,但没有收到任何明显的速度提高。

09-11 19:35
查看更多