Entity Framework新增Include(Quotes)后API响应时间骤增问题咨询
你遇到的性能问题本质是EF Core默认查询模式下的笛卡尔积爆炸问题:
- 你当前的查询里已经包含了Skins、Skills、LimitBreaks、Gallery、EquippableSlots多个集合类型的导航属性,再加Quotes这个集合之后,EF Core默认会把所有关联表用JOIN拼接成单条SQL查询
- 多集合JOIN的结果行数是所有集合数量的乘积,而非加和。比如单艘船有5个皮肤、4个技能、3个突破信息、3个画廊内容、2个装备槽,再加30条台词,最终查询返回的行数是
5*4*3*3*2*30=10800行,每一行都会重复携带所有单值属性(基础属性、建造信息、声优信息等)的冗余数据,直接导致数据库返回流量暴增,EF Core实体映射耗时也随之飙升。
解决方案
- 优先使用拆分查询(Split Query)
在你的查询末尾添加.AsSplitQuery()方法,EF Core会将每个集合导航属性的加载拆分为独立的SQL查询,完全避免笛卡尔积冗余,性能可以恢复到之前的水平,修改后代码示例:
await _context.Ships .Include(s => s.Stars) .Include(s => s.Skins) .Include(s => s.Skills) .Include(s => s.LimitBreaks) .Include(s => s.Gallery) .Include(s => s.EquippableSlots) .Include(s => s.Quotes) .Include(s => s.BaseStats) .Include(s => s.Level100Stats) .Include(s => s.Level120Stats) .Include(s => s.Level100RetrofitStats) .Include(s => s.Level120RetrofitStats) .Include(s => s.EnhanceValue) .Include(s => s.ScrapValue) .Include(s => s.Construction) .Include(s => s.Construction.Availability) .Include(s => s.Artist) .Include(s => s.Pixiv) .Include(s => s.Twitter) .Include(s => s.Web) .Include(s => s.VoiceActor) .AsSplitQuery() // 新增拆分查询配置 .SingleAsync(ship => ship.Name == name);
- 检查外键索引
确认ShipQuotes表关联Ship的外键字段已创建索引,避免关联查询时触发全表扫描。 - 可选优化:使用投影查询
如果接口只需要返回固定字段,可以用.Select()手动映射DTO,只查询需要的字段,进一步减少数据传输量和映射耗时。
内容的提问来源于stack exchange,提问作者Myuuiii
相关产品推荐
相关产品推荐

