2017-06-02 70 views
1

我寫它看起來像這樣的代碼:加快LINQ查詢(從表中選擇數據)

using(var ctx = new myentitiesContext()) 
{ 
    var currentLoggedUser = ctx.Users.FirstOrDefault(x=>x.Email==User.Identity.Name); 
    var items = ctx.Items.Where(x=>x.Sales>0 && x.UserId==currentLoggedUser.UserId).ToList(); 
} 

正如你可以看到它是從數據庫中一個簡單的選擇。但棘手的部分是,有時我可以選擇大量的數據(一次50-100k條記錄)。所以我一直在想,有什麼方法可以調整LINQ在數據被從表中拉出時更快地執行?

我已經在我的表中創建了FK UserId中的索引,因此部分完成了。

我的問題是,有沒有什麼辦法可以通過上下文配置部分的一些調整來加速LINQ查詢,或者通過創建編譯查詢或者通過其他方法來加速LINQ查詢?

P.S.球員,會這樣的工作很好:

ctx.Configuration.AutoDetectChangesEnabled = false; 

    // my queries... 

    ctx.Configuration.AutoDetectChangesEnabled = true; 
+2

有各種方法可以告訴EF採取一些快捷方式,例如'AutoDetectChanges'標誌和'.AsNoTracking()',但加速查詢的絕對最佳方式是避免調用'.ToList()'直到您需要內存中所有元素的實際列表(在任何過濾器運行之後)。 – Scott

+0

@Scott The .AsNoTracking是我的對象上下文的擴展方法嗎? – User987

+1

「用戶」的主鍵是什麼?如果你使用Find來代替FirstOrDefault,那麼你可以節省一些時間。我也建議將主鍵值對用戶的身份進行緩存,以防止不斷查找它。 – Clint

回答

1

此外還有其他用戶編寫的內容。您可以禁用延遲加載。這樣,如果Items Db Table引用了其他表,除非你絕對需要它們,否則它們將不會與該Items一起加載。檢查這些鏈接

  1. thecodegarden
  2. mehdi

還有一個認爲我會建議是,你必須登錄,您的LINQ表達式創建SQL查詢,並嘗試與你的DBA對其進行優化。您可以通過在DbContext.Database.Log上添加Action<string>代表來執行此操作,該代表將發出connection.Open()connection.Close()之間的所有內容。您還可以從您的IQueryableIQueryable<T>中取出sql查詢,並在您的IQueryable變量上調用.ToString()方法。

-2

你應該先做投影。例如,這樣的:

var items = ctx.Items.Where(x=>x.Sales>0 && x.UserId==currentLoggedUser.UserId).ToList(); 

會更好,如果你寫這樣的:

var items = ctx.Items.Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0).ToList(); 

如果你並不需要所有的對象你之前,使用「選擇」條款「Where」和項目只是你需要降低成本的屬性,如下所示:

ctx.Items.Select(e=>new {e.UserID,e.Sales}).Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0).ToList(); 
+1

實際上,當與數據庫交談時,沒有任何問題。 – NetMage