efcore: EF Core 1.0 RC2: async queries so much slower than sync
One of the features that I have missed in EF6 it was the possibility to use includes with raw quieries. This is possible with EF Core, something like this:
await myDbContext.MyDbSet.FromSql("Select * from Mytable")
.Include(x=> x.Property1.Property2.Property6)
.Include(x=> x.Property3.Property4.Property5)
.Include(x=> x.Property7.Property7)
.ToListAsync();
The problem is that this query it is very slow, about 5 minutes. When I use LinQ the time is slower, much slower, but in my case I wanted to use raw quieries because I want to use the hints of Sql Server to block some rows.
I am using Express Profiler to get the query that EF Core send to Sql Server, and if I run this query in Sql Server Management Studio, it takes just 3 seconds to complete. So the problem it seems to be in EF Core.
Also, with Express Profiler I see that the query makes 370000 reads that takes 310000 seconds (about 5 minutes). But I don’t understand this because in SSMS takes 3 seconds this query.
I have tried this query:
await myDbContext.MyDbSet.FromSql("Select * from Mytable")
.ToListAsync();
This takes 3 seconds, but if I try this one:
await myDbContext.MyDbSet.FromSql("Select * from Mytable")
.Include(x=> x.Property1.Property2)
.ToListAsync();
It takes 77 seconds.
With EF6, the same query with all the includes takes 3 secods, and I am using a IQueryable that has to create the t-sql query. I have expected that EF Core would have a better performace than EF6, at least not so bad. The problem with EF6 is that if I want to use the hints of Sql Server I have to do two queries, one with the raw sql to block the rows and another query, with LinQ, to bring the entities to the dbContext and the includes.
Anyway, if I use the same query with LinQ with EF Core, it takes a bit more, about 4 seconds, so it has worse performace.
Really I don’t know if I am doing something wrong or EF Core with the includes has worse performance than EF6. And with raw query with includes it is very bad.
I guess that EF Core has problem populating the navigation properties, because really the t-sql that send to the database is very fast, the total time it is very big.
Thanks.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 45 (21 by maintainers)
Commits related to this issue
- Switched to sync EF. Added missing CorsPolicyService to builder extensions — committed to IdentityServer/IdentityServer4.EntityFramework by deleted user 8 years ago
- Revert revision 9f903e4 "Temp workaround: execute queries synchronously on the server side, because async execution is slow due to the known performance issue in EFC https://github.com/aspnet/EntityFr... — committed to azabluda/InfoCarrier.Core by azabluda 7 years ago
Update: I have a fix coming that yields a ~70% speed-up for async Include queries.
@rowanmiller @julielerman “anti-pattern” seems too strong here. I’m pretty sure this particular case is related to the heavy use of Include. When I remove them, the numbers are much better.
I just want to say thanks for the hard work, and me and my team are waiting on this fix to be released
“anti-pattern” because of perf issues or is there some other reason why it doesn’t make sense to do async anyway? Like because of the layers of dependencies that async/await forces you into and that can mess up the IoC services? Or “it’s in EFCore but not as good as we want it yet so for now…stick with sync”? Thanks for any clarity. And really glad to see @ljw1004 jumping in here.
@rowanmiller Is there a branch / beta release we can use to leverage this before the Fall/Winter 1.1 release? We’ve just undergone a large migration from EFC1.0 back down to EF6 and this turned out to be one of the major reasons – amongst others (in-memory computations / querying limitations).
We were getting full timeouts (30s) and very slow queries (8-20s) on a pre-production environment (no live users yet). All of our DB queries are async and not using them really is a deal-breaker – ie: one of the core reasons we are on C#/.NET in the first place.
Since migrations don’t play nicely amongst the two frameworks we would really prefer to stay on EFCore if at all possible. We would need to be able to leverage this right away if so though – otherwise we will probably revisit an EF6–>EFCore migration again in mid-2017 at the earliest. This migration/experimentation cost was way too high for us to get burned this way again.
@ctolkien correct, this will ship in a following release.
@gdoron sounds like you maybe just want to disable client side evaluation? That way you get an exception when something isn’t getting pushed to the database (rather than having it transparently eval on the client).