【问题标题】:Filter, order and paging implementation too slow过滤、排序和分页实现太慢
【发布时间】:2019-07-21 08:53:20
【问题描述】:

我正在实现一个数据库,我想在其中包含高级过滤器和手动分页搜索,但我很难使后端方法高效。如果实体数量足够大(我目前正在测试 700 个实体),以下代码通常会在加载页面时导致服务器挂起或出现内部服务器错误 (500)。

我的测试得出结论,如果我删除排序和过滤部分(仅左分页),算法可以处理大量数据,但我想尝试满足所有要求。

这是我在后端的代码:

public IQueryable<Movie> GetMovies(int page, int pageSize, out int totalMoviesCount, 
string sortOrder, string searchString, string actorName, string genreName)
        {
            var Movies = from m in _dbContext.Movies
             .Include(m => m.MoviesDirectors)
             .ThenInclude(ba => ba.Director)
             .Include(m => m.MoviesGenres)
             .ThenInclude(mg => mg.Genre)
             .Include(m => m.MoviesActors)
             .ThenInclude(ma => ma.Actor)
                         select m;

            // filter
            if (!string.IsNullOrEmpty(searchString))
            {
                Movies = Movies.Where(m => m.Title.Contains(searchString));
            }
            //
            // .. genre and actor filtering

            //order
            switch (sortOrder)
            {
                case "title":
                    Movies = Movies.OrderBy(m => m.Title);
                    break;
                case "titledesc":
                    Movies = Movies.OrderByDescending(m => m.Title);
                    break;
                case "year":
                    Movies = Movies.OrderBy(m => m.PublishDate).ThenBy(m => m.Title);
                    break;
                    //
                    // .. likes, rating and default ordering
            }
            totalMoviesCount = Movies.Count();

            return Movies
             .Skip(page * pageSize)
             .Take(pageSize);
        }

我认为可以让它工作,但我不知道我缺少的部分在哪里。

【问题讨论】:

  • 嗨,欢迎来到堆栈溢出。您是否尝试添加数据库索引?
  • 700 不算什么。您是否尝试过在管理工作室中生成的查询? (如果这是 Sql Server)。您更有可能遗漏了一些重要指标。如果您要询问有关性能的问题,您一定已经排除了通常的嫌疑人(索引、数据库服务器资源、网络延迟等主要问题)。

标签: c# linq asp.net-core entity-framework-core


【解决方案1】:

首先对 _dbContext.Movies 进行必要的过滤。在此过滤之后,您可以简单地从其他表中加载所有其他数据。这将使 JOIN 更快,因为您不会加入每部电影,而只会加入您感兴趣的电影。

附:变量应该以小写开头:)

【讨论】:

  • 这里没有“第一”。查询首先组合,而不是在.Count() 之前执行,然后在return 语句中执行。事实上,EF 核心会执行单独的过滤和分页查询来获取包含的数据。所以没有加入“每部电影”。
猜你喜欢
  • 2018-01-01
  • 2019-07-09
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
相关资源
最近更新 更多