C# 实体框架查询太慢

C# 实体框架查询太慢,c#,.net,entity-framework,asp.net-core,entity-framework-core,C#,.net,Entity Framework,Asp.net Core,Entity Framework Core,我必须对你的数据库进行复杂的查询。但查询以8000毫秒结束。我做错什么了吗?我使用.NET1.1和EntityFramework核心1.1.2版本 var fol = _context.UserRelations .Where(u => u.FollowerId == id && u.State == true) .Select(p => p.FollowingId)

我必须对你的数据库进行复杂的查询。但查询以8000毫秒结束。我做错什么了吗?我使用.NET1.1和EntityFramework核心1.1.2版本

var fol = _context.UserRelations
                  .Where(u => u.FollowerId == id && u.State == true)
                  .Select(p => p.FollowingId)
                  .ToArray();

var Votes = await _context.Votes
                          .OrderByDescending(c => c.CreationDate)
                          .Skip(pageSize * pageIndex)
                          .Take(pageSize)
                          .Where(fo => fol.Contains(fo.UserId))
                          .Select(vote => new
                {
                    Id = vote.Id,
                    VoteQuestions = vote.VoteQuestions,
                    VoteImages = _context.VoteMedias.Where(m => m.VoteId == vote.Id)
                        .Select(k => k.MediaUrl.ToString()),

                    Options =  _context.VoteOptions.Where(m => m.VoteId == vote.Id).Select( ques => new
                    {
                        OptionsID = ques.Id,
                        OptionsName =  ques.VoteOption,
                        OptionsCount =  ques.VoteRating.Count(cout => cout.VoteOptionsId == ques.Id),
                    }),
                    User = _context.Users.Where(u => u.Id == vote.UserId).Select(usr => new
                    {
                        Id = usr.Id,
                        Name = usr.UserProperties.Where(o => o.UserId == vote.UserId).Select(l => l.Name.ToString())
                            .First(),
                        Surname = usr.UserProperties.Where(o => o.UserId == vote.UserId)
                            .Select(l => l.SurName.ToString()).First(),
                        ProfileImage = usr.UserProfileImages.Where(h => h.UserId == vote.UserId && h.State == true)
                            .Select(n => n.ImageUrl.ToString()).First()
                    }),
                    NextPage = nextPage
                }).ToListAsync();

如注释中所述,您可能正在执行100、1000或10000个查询。对于数据库中与第一个结果匹配的每一个
投票
,您将执行3个其他查询

对于第一次查询产生的1000张投票,您需要执行3000次其他查询以获取数据。那太疯狂了

您必须使用EF Cores功能以很少的查询获取此数据。如果你的模型设计得很好,它很容易

加载没有投影的平面模型时(使用
。选择
),必须使用
。Include
告诉EF应该加载哪些其他相关实体

// Assuming your navigation property is called VoteMedia
await _context.Votes.
    .Include(vote => vote.VoteMedia)
    ...
这将加载所有带有投票的
VoteMedia
对象。因此,不需要额外的查询来获取它们

但是如果使用项目,则不需要调用
.Include
(事实上,当您在投影中引用导航属性时,甚至会忽略这些调用)


如注释中所述,您可能正在执行100、1000或10000个查询。对于数据库中与第一个结果匹配的每一个
投票
,您将执行3个其他查询

对于第一次查询产生的1000张投票,您需要执行3000次其他查询以获取数据。那太疯狂了

您必须使用EF Cores功能以很少的查询获取此数据。如果你的模型设计得很好,它很容易

加载没有投影的平面模型时(使用
。选择
),必须使用
。Include
告诉EF应该加载哪些其他相关实体

// Assuming your navigation property is called VoteMedia
await _context.Votes.
    .Include(vote => vote.VoteMedia)
    ...
这将加载所有带有投票的
VoteMedia
对象。因此,不需要额外的查询来获取它们

但是如果使用项目,则不需要调用
.Include
(事实上,当您在投影中引用导航属性时,甚至会忽略这些调用)


请看一看向服务器生成的SQL查询(以及该查询的结果)。对于SQL Server,最好的选择是SQL Server Profiler,对于其他服务器也有一些方法

  • 创建两个查询。首先创建
    fol
    数组,然后使用Contains将其传递到第二个查询中。你知道这是怎么回事吗?您可能会使用数组中相同数量的项来生成查询。它既不美观也不高效。这里没有必要,将它合并到主查询中,您将只有一个参数

  • 您在过滤之前进行分页,这真的是应该的工作方式吗?另外,还可以看看其他基于ID过滤而不是简单跳过的分页方式

  • 您在一个查询中执行了太多的辅助查询。当查询三个子列表(每个子列表包含100个项目)时,不会得到300行。要在一个查询中获得它,您需要创建join并实际获得100*100*100=1000000行。除非您确定框架可以将其拆分为多个查询(可能无法),否则您应该在单独的查询中查询子列表。这可能是您遇到的主要性能问题

  • 请使用单数来命名表格,而不是复数

  • 对于性能分析来说,索引结构和执行计划是非常重要的信息,没有它们你就说不出什么


查看您向服务器生成的SQL查询(以及该查询的结果)。对于SQL Server,最好的选择是SQL Server Profiler,对于其他服务器也有一些方法

  • 创建两个查询。首先创建
    fol
    数组,然后使用Contains将其传递到第二个查询中。你知道这是怎么回事吗?您可能会使用数组中相同数量的项来生成查询。它既不美观也不高效。这里没有必要,将它合并到主查询中,您将只有一个参数

  • 您在过滤之前进行分页,这真的是应该的工作方式吗?另外,还可以看看其他基于ID过滤而不是简单跳过的分页方式

  • 您在一个查询中执行了太多的辅助查询。当查询三个子列表(每个子列表包含100个项目)时,不会得到300行。要在一个查询中获得它,您需要创建join并实际获得100*100*100=1000000行。除非您确定框架可以将其拆分为多个查询(可能无法),否则您应该在单独的查询中查询子列表。这可能是您遇到的主要性能问题

  • 请使用单数来命名表格,而不是复数

  • 对于性能分析来说,索引结构和执行计划是非常重要的信息,没有它们你就说不出什么


您的数据库中是否有一个或多个相关索引?(您应该能够在VS的输出窗口中看到SQL请求,然后可以在SQL Server Management Studio中运行此请求并查看实际执行计划)我的数据库架构。乍一看,它看起来有点健谈,难怪它很慢。你知道你在那里做什么吗?对于每一次投票,您将执行3个查询。所以,如果你有1000张选票,你将对你的数据库进行3000(!!!!)次查询。你怎么能指望这么快?您应该考虑要获取的数据,并使用EF Cores在几个查询中获取大部分数据您的数据库中是否有一个或多个相关索引?(您应该能够在VS的输出窗口中看到SQL请求,然后可以在SQL Server Management Studio中运行此请求并查看实际执行计划)我的数据库架构。乍一看,它看起来有点健谈,难怪它很慢。你知道你在那里做什么吗?对于每一次投票,您将执行3个查询。所以,如果你有1000张选票,你将对你的数据库进行3000(!!!!)次查询。你怎么能指望这么快?你应该考虑一下