EF Core 中使用 .Include() 获取多个子实体的查询非常慢?
Very slow query in EF Core that fetches multiple children entities with .Include()?
我在下面有这个查询,它获取所有这些子实体(例如 PracticedStyles、ReceivedReviews、InstructedPoses 等)
我只需要这些子集合的 .count()。
问题 - 是否有更快的方法 运行 此查询获取这些包含的计数,然后使用下面的此查询?
运行 时间约为 4-7 秒,数据库中的数据非常少。
var userWithChildren = await _dbContext.Users
.Include(p => p.Yogabands.Where(p => p.IsActive == true))
.Include(p => p.PracticedStyles)
.Include(p => p.PracticedPoses)
.Include(p => p.ReceivedReviews)
.Include(p => p.InstructedStyles)
.Include(p => p.InstructedPoses)
.Include(p => p.InstructorPrograms)
.FirstOrDefaultAsync(user => user.UserName == userName);
绝对有。 Include
是一种钝器,它 returns 连接每一行。更糟糕的是,由于 SQL 的操作方式,您会以规范化形式返回结果,这意味着返回的总行数是所有这些计数相乘后的结果。拥有尽可能多的包含,这可能是数万行。
你要的是投影,像这样:
var userWithChildren = await _dbContext.Users
.Select(p => new
{
user = p,
YogaBandCount = p.Yogabands.Where(yb => yb.IsActive == true).Count(),
PracticedStylesCount = p.PracticedStyles.Count(),
PracticedPosesCount = p.PracticedPoses.Count()
ReceivedReviewsCount = p.ReceivedReviews.Count(),
InstructedStylesCount = p.InstructedStyles.Count(),
InstructedPosesCount = p.InstructedPoses.Count()
InstructorProgramsCount = p.InstructorPrograms.Count()
})
.FirstOrDefaultAsync(p => p.user.UserName == userName);
这将创建一个匿名的 class,其中包含用户以及您需要的所有计数。
我在下面有这个查询,它获取所有这些子实体(例如 PracticedStyles、ReceivedReviews、InstructedPoses 等)
我只需要这些子集合的 .count()。
问题 - 是否有更快的方法 运行 此查询获取这些包含的计数,然后使用下面的此查询? 运行 时间约为 4-7 秒,数据库中的数据非常少。
var userWithChildren = await _dbContext.Users
.Include(p => p.Yogabands.Where(p => p.IsActive == true))
.Include(p => p.PracticedStyles)
.Include(p => p.PracticedPoses)
.Include(p => p.ReceivedReviews)
.Include(p => p.InstructedStyles)
.Include(p => p.InstructedPoses)
.Include(p => p.InstructorPrograms)
.FirstOrDefaultAsync(user => user.UserName == userName);
绝对有。 Include
是一种钝器,它 returns 连接每一行。更糟糕的是,由于 SQL 的操作方式,您会以规范化形式返回结果,这意味着返回的总行数是所有这些计数相乘后的结果。拥有尽可能多的包含,这可能是数万行。
你要的是投影,像这样:
var userWithChildren = await _dbContext.Users
.Select(p => new
{
user = p,
YogaBandCount = p.Yogabands.Where(yb => yb.IsActive == true).Count(),
PracticedStylesCount = p.PracticedStyles.Count(),
PracticedPosesCount = p.PracticedPoses.Count()
ReceivedReviewsCount = p.ReceivedReviews.Count(),
InstructedStylesCount = p.InstructedStyles.Count(),
InstructedPosesCount = p.InstructedPoses.Count()
InstructorProgramsCount = p.InstructorPrograms.Count()
})
.FirstOrDefaultAsync(p => p.user.UserName == userName);
这将创建一个匿名的 class,其中包含用户以及您需要的所有计数。