EF Core使用.Include()加载多子实体查询过慢,如何快速获取子集合计数?
性能差的核心原因
你当前查询慢的核心原因是:Include 会将所有关联子实体的全量数据加载到内存,你后续要的 .Count() 本质是在内存中对已加载的实体集合计数,哪怕数据量小,多关联查询产生的笛卡尔积、大量无用数据传输、内存序列化开销也会导致耗时很高。
最优解决方案
直接使用投影查询,所有计数逻辑在数据库侧完成,不需要加载任何子实体数据,代码示例如下:
// 可以根据需要自定义DTO类接收结果,也可以直接用匿名类 var userStats = await _dbContext.Users .Where(u => u.UserName == userName) .Select(u => new { // 对应过滤后的活跃Yogabands计数 ActiveYogabandsCount = u.Yogabands.Count(y => y.IsActive), PracticedStylesCount = u.PracticedStyles.Count(), PracticedPosesCount = u.PracticedPoses.Count(), ReceivedReviewsCount = u.ReceivedReviews.Count(), InstructedStylesCount = u.InstructedStyles.Count(), InstructedPosesCount = u.InstructedPoses.Count(), InstructorProgramsCount = u.InstructorPrograms.Count(), // 需要用户基础字段也可以在这里追加,比如: UserId = u.Id, NickName = u.NickName }) .FirstOrDefaultAsync();
方案优势
- EF Core会自动生成优化的SQL,所有计数操作都在数据库端执行,最终仅返回你需要的计数字段,无多余数据传输
- 不需要加载任何子实体,完全避免了多关联查询的笛卡尔积问题、实体序列化和内存开销,正常场景下耗时可以降到毫秒级
额外优化建议
- 给
Users表的UserName字段添加非聚集索引,避免查询用户时走全表扫描,进一步降低查询耗时
内容的提问来源于stack exchange,提问作者chuckd
相关产品推荐
相关产品推荐

