简体   繁体   中英

How to optimise this ef core query?

I'm using EF Core 3.0 code first with MSSQL database. I have big table that has ~5 million records. I have indexes on ProfileId, EventId and UnitId . This query takes ~25-30 seconds to execute. Is it normal or there is a way to optimize it?

await (from x in _dbContext.EventTable
                             where x.EventId == request.EventId
                             group x by new { x.ProfileId, x.UnitId } into grouped
                             select new
                             {
                                 ProfileId = grouped.Key.ProfileId,
                                 UnitId = grouped.Key.UnitId,
                                 Sum = grouped.Sum(a => a.Count * a.Price)
                             }).AsNoTracking().ToListAsync();

I tried to loos through profileIds , adding another WHERE clause and removing ProfileId from grouping parameter, but it worked slower.

Capture the SQL being executed with a profiling tool (SSMS has one, or Express Profiler) then run that within SSMS /w execution plan enabled. This may highlight an indexing improvement. If the execution time in SSMS roughly correlates to what you're seeing in EF then the only real avenue of improvement will be hardware on the SQL box. You are running a query that will touch 5m rows any way you look at it.

Operations like this are not that uncommon, just not something that a user would expect to sit and wait for. This is more of a reporting-type request so when faced with requirements like this I would look at options to have users queue up a request where they can receive a notification when the operation completes to fetch the results. This would be set up to prevent users from repeatedly requesting updates ("not sure if I clicked" type spams) or also considerations to ensure too many requests from multiple users aren't kicked off simultaneously. Ideally this would be a candidate to run off a read-only reporting replica rather than the read-write production DB to avoid locks slowing/interfering with regular operations.

Try to remove ToListAsync(). Or replace it with AsQueryableAsync(). Add ToList slow performance down.

await (from x in _dbContext.EventTable
                         where x.EventId == request.EventId
                         group x by new { x.ProfileId, x.UnitId } into grouped
                         select new
                         {
                             ProfileId = grouped.Key.ProfileId,
                             UnitId = grouped.Key.UnitId,
                             Sum = grouped.Sum(a => a.Count * a.Price)
                         });

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