-1

我有頁與分頁和電影搜索,電影表有388262記錄。沒有使用搜索,下面的代碼工作得很快。但是當使用搜索(vm.Search被填充)時,檢索記錄變得緩慢。如何結合LINQ包含查詢與所有記錄計數和檢索與偏移的記錄

所以基本上它做了兩次contains/like查詢,一次是用偏移量返回結果,一次是沒有偏移量的計數,這是正確的,但是有沒有辦法將這個結合起來以提高性能?

奇怪的是,當我使用日誌中的查詢並使用SSMS(SQL Server Management Studio)直接在數據庫上執行它們時。它在大約2秒內相當快地執行兩個查詢。使用code/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); 
} 

SQL日誌從行與跳躍和Take:

SELECT COUNT(*) 
FROM [Movie] AS [m] 
WHERE [m].[title] LIKE ('%' + @__vm_Search_0) + '%' 
:從伯爵的線

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 

SQL日誌

+0

聽起來像你的問題與你問的沒有任何關係。 EF中存在性能問題。你應該解決這個問題。嘗試清除查詢緩存。 – Aron

+0

我不知道爲什麼你必須調用_movieRepository.GetQueryable()。除非您的_movieRepository不是'IQueryable ',否則這會檢測redudant。你能發佈它的定義嗎?如果它是'IEnumerable ',那麼這就是你的問題:它發生在整個數據集的內存中 – Tseng

+0

@Tseng _movieRepository是來自存儲庫模式的存儲庫。 GetQueryable是我自己做的一個函數,它爲Movie實體返回一個IQueryable。當我更多地使用這個函數時,它會在movieRepository中獲得它自己的函數。而不是將這些邏輯直接放在我的控制器中。 –

回答

0

下面的代碼將同時運行這兩個查詢。但是,這段代碼只會更快地執行〜[延遲到SQL服務器],這應該在10ms左右。

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. 清除查詢緩存

檢查事項

  1. 你準確的標杆?這是8秒的JITer,然後是2秒的實際運行?
  2. 任何奇怪的HTTP系統像代理方式?
  3. DNS?
  4. 您是否正在發佈或調試模式下運行?
相關問題