简体   繁体   English

如何优化这个 ef 核心查询?

[英]How to optimise this ef core query?

I'm using EF Core 3.0 code first with MSSQL database.我首先将 EF Core 3.0 代码与 MSSQL 数据库一起使用。 I have big table that has ~5 million records.我有一张大桌子,里面有大约 500 万条记录。 I have indexes on ProfileId, EventId and UnitId .我在ProfileId, EventId UnitIdUnitId上有索引。 This query takes ~25-30 seconds to execute.执行此查询需要大约 25-30 秒。 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.我试图通过profileIds ,添加另一个WHERE子句并从分组参数中删除ProfileId ,但它的工作速度较慢。

Capture the SQL being executed with a profiling tool (SSMS has one, or Express Profiler) then run that within SSMS /w execution plan enabled.使用分析工具(SSMS 有一个或 Express Profiler)捕获正在执行的 SQL,然后在启用的 SSMS /w 执行计划中运行该工具。 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.如果 SSMS 中的执行时间与您在 EF 中看到的大致相关,那么唯一真正的改进途径将是 SQL 盒上的硬件。 You are running a query that will touch 5m rows any way you look at it.您正在运行的查询将涉及 500 万行,无论您怎么看。

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().尝试删除 ToListAsync()。 Or replace it with AsQueryableAsync().或者用 AsQueryableAsync() 替换它。 Add ToList slow performance down.添加 ToList 会降低性能。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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