Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 traffic EF traffic

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.

like image 535
Dmitri Trofimov Avatar asked Dec 09 '15 09:12

Dmitri Trofimov


1 Answers

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.

like image 137
Dmitri Trofimov Avatar answered Sep 30 '22 16:09

Dmitri Trofimov