简体   繁体   中英

Entity Framework data reading performance

I have an interesting situation. When I run a query on remote SQL server in Microsoft SQL Server Management Studio it runs fast (12 sec), but when I run the same query in Entity Framework using DbContext.Database.SqlQuery<EntityType>(script) it takes 48 seconds.

I tried setting set arithabort on . The setting got applied but it didn't change the performance. I am not able to provide query execution plans, because I only have limited permissions on the SQL server. But I can say 100% that this is not the query issue.

Consider this query:

declare @t table (...)
insert into @t
select <long query>

select top 1 * from @t

The @t variable contains about 35k rows. The execution times are pretty much similar in EF and in SSMS. But when I remove the top 1 then strange thing begin to happen. In SSMS I get 10 sec, but in EF about 40 sec.

I guess this little experiment can rule out the possibility of SQL Server choosing the wrong execution plan and slowing things down.

Another point of interest would be entity materialization done by EF. I think this also is not a bottleneck, because when I run a similar query with similar size result set on a local SQL Express — I get the results almost instantly in both cases.

So my next guess is network issues. I installed Microsoft Network Monitor 3.4 and monitored network traffic for both SSMS and EF. The interestig thing I found out is for some reason there are many packets of smaller size and also some TLS packets in EF version. In SSMS version packet size is more stable and there are no TLS packets.

So the question is: is it possible to speed up the EF version? What are those TLS packets, is it possible to get rid of them?

SSMS流量 EF流量

Update
Entity Framework v6.1.3
.NET v4.5.1
SQL Server v10.50.2550.0
Local SQLExpress v12.0.4213.0
Windows 7 Pro

Update

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

This code yields time-wise same results.

I have done some research and experimenting, and it appears that adding packet size=32768 (this is the maximum size) option to connection string tends to increase the speed to almost SSMS levels. Interestingly, TCP packets that I receive do not increase their size.

I have experimented with other connection string options as well but did not receive any noticeable speed increase.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM