I am trying to run parallel queries in EF core. This is what my POC code looks like
IQueryable<ClaimHeader> query = repo.GetAll();
IQueryable<ClaimHeader> query1 = repo.GetAll();
IQueryable<ClaimHeader> query2 = repo.GetAll();
IQueryable<ClaimHeader> query3 = repo.GetAll();
IQueryable<ClaimHeader> query4 = repo.GetAll();
query = CreateIQueryableFromParameters(queryParameters, query);
query1 = CreateIQueryableFromParameters(queryParameters, query1 );
query2 = CreateIQueryableFromParameters(queryParameters, query2 );
query3 = CreateIQueryableFromParameters(queryParameters, query3 );
query4 = CreateIQueryableFromParameters(queryParameters, query4 );
var a = query.CountAsync();
var b = query1.ToListAsync();
var c = query2.ToListAsync();
var d = query3.ToListAsync();
var e = query4.ToListAsync();
await Task.WhenAll(a, b,c,d,e);
In C# it is running without waiting for the previous query.
I traced all these in SQL server profiler. The actual db query is running sequentially. Basically the db query generated by query2
only starts after the query of query1
ends.
Is this a normal behavior? How can i achieve true parallelism ?
Anwering my own question
The problem is the shared repo instance.
IQueryable<ClaimHeader> query = repo.GetAll();
IQueryable<ClaimHeader> query1 = repo.GetAll();
IQueryable<ClaimHeader> query2 = repo.GetAll();
IQueryable<ClaimHeader> query3 = repo.GetAll();
IQueryable<ClaimHeader> query4 = repo.GetAll();
Althought this will not throw expception due to parallel queries. It will not run query in db in parallel. I had to get new instance of repository for each parallel query so the solution would be something like
IQueryable<ClaimHeader> query = repo.GetAll();
IQueryable<ClaimHeader> query1 = repo1.GetAll();
IQueryable<ClaimHeader> query2 = repo2.GetAll();
IQueryable<ClaimHeader> query3 = repo3.GetAll();
IQueryable<ClaimHeader> query4 = repo4.GetAll();
This works and verfied in Profiler.