如何组合LINQ包含查询与所有记录的计数并检索偏移量为

时间:2016-05-23 22:35:33

标签: entity-framework linq asp.net-core entity-framework-core azure-sql-database

我有分页和搜索电影的页面,电影表有388262条记录。不使用搜索,以下代码可以快速运行。但是当使用搜索(vm.Search被填充)时,检索记录变得很慢。

所以基本上它做了两次包含/喜欢的查询,一次用于返回带偏移的结果,另一次用于没有偏移的计数,这是正确的,但有没有办法将它结合起来进行改进性能

奇怪的是,当我使用日志中的查询并使用SSMS(SQL Server Management Studio)直接在数据库上执行它们时。它在大约2秒内快速执行两个查询。使用代码/ linq执行它需要大约10秒钟?

我执行LINQ的代码:

public IActionResult Index(MovieIndexViewModel vm) {
    IQueryable<Movie> query = _movieRepository.GetQueryable().AsNoTracking()
        .Select(m => new Movie {
            movie_id = m.movie_id,
            title = m.title,
            description = m.description
        });

    if (!string.IsNullOrWhiteSpace(vm.Search)) {
        query = query.Where(m => m.title.Contains(vm.Search));
    }

    vm.Movies = query.Skip(_pageSize * (vm.Page - 1)).Take(_pageSize).ToList();
    vm.PageSize = _pageSize;
    vm.TotalItemCount = query.Count();
    return View(vm);
}

Skip and Take:

行中的SQL日志
SELECT [m].[movie_id], [m].[title], [m].[description]
FROM [Movie] AS [m]
WHERE [m].[title] LIKE ('%' + @__vm_Search_0) + '%'
ORDER BY @@ROWCOUNT
OFFSET 0 ROWS FETCH NEXT 30 ROWS ONLY

来自Count:

的行的SQL日志
SELECT COUNT(*)
FROM [Movie] AS [m]
WHERE [m].[title] LIKE ('%' + @__vm_Search_0) + '%'

1 个答案:

答案 0 :(得分:0)

以下代码将同时运行两个查询。但是,此代码只会更快地执行〜[SQL服务器的延迟],这应该是10毫秒的数量级。

public async Task<IActionResult> Index(MovieIndexViewModel vm) {
    IQueryable<Movie> query = _movieRepository.GetQueryable().AsNoTracking()
        .Select(m => new Movie {
            movie_id = m.movie_id,
            title = m.title,
            description = m.description
        });

    if (!string.IsNullOrWhiteSpace(vm.Search)) {
        query = query.Where(m => m.title.Contains(vm.Search));
    }
    var moviesTask = query.Skip(_pageSize * (vm.Page - 1)).Take(_pageSize).ToListAsync();
    var countTask = query.CountAsync();
    vm.Movies = await moviesTask;
    vm.PageSize = _pageSize;
    vm.TotalItemCount = await countTask;
    return View(vm);
}

我怀疑你并不是在寻找10ms的性能调整。相反,请关注查询计划。

你应该尝试的事情。

  1. .OrderBy(m => m.title)添加到query
  2. 添加更多指数
  3. 清除查询缓存
  4. 要检查的事项

    1. 您准确进行基准测试了吗?那是8秒的JITer,然后是2秒的实际运行?
    2. 任何奇怪的HTTP系统,比如代理方式吗?
    3. DNS?
    4. 您是在发布模式还是调试模式下运行?