0

我在DbSet上有一個Linq查詢,它碰到一個表並抓取65k行。查詢大約需要3分鐘,對我來說這似乎太明顯了。雖然我沒有比較的路線,但我確信這可以得到改善。我對EF和Linq相對陌生,所以我懷疑我也可能以一種很大的「否」來構建我的查詢。提高慢速查詢的性能 - 可能通過禁用更改跟蹤

我知道變化跟蹤是EF花費大部分時間的地方,並且在相關實體上啓用,所以也許我應該關閉它(如果是這樣,如何)?

下面的代碼:

ReportTarget reportTarget = repository.GetById(reportTargetId); 
if (reportTarget != null) 
{ 
    ReportsBundle targetBundle = reportTarget.SavedReportsBundles.SingleOrDefault(rb => rb.ReportsBundleId == target.ReportsBundleId); 
    if (targetBundle != null) 
    { 
    } 
} 

這下一行需要3分鐘來執行(65K記錄):

IPoint[] pointsData = targetBundle.ReportEntries 
          .Where(e => ... a few conditions) 
          .Select((entry, i) => new 
           { 
           rowID = entry.EntryId, 
           x = entry.Profit, 
           y = i, 
           weight = target.HiddenPoints.Contains(entry.EntryId) ? 0 : 1, 
           group = 0 
           }.ActLike<IPoint>()) 
          .ToArray(); 

注: ActLike()是從使用Impromptu Interface庫。 NET DLR可以動態地實現實現接口的對象的動態代理。我懷疑這是瓶頸。

如何優化這個特定DbSet(TradesReportEntries)我會查詢這個表大型數據集(IPoint[] S)經常

回答

1

嗯,它看起來像你加載一個實體對象,然後表現查詢導航屬性。當發生這種情況時,EF加載所有相關實體FIRST(通過延遲加載),然後在整個集合上執行查詢。這可能是您出現性能問題的原因。對收集

嘗試查詢使用下列內容:

context.Entry(targetBundle) 
    .Collection(p => p.TradesReportEntries) 
    .Query() 
    .Where(e => <your filter here>) 
    .Select(<your projection here>) 

這可以讓你除了用於處理加載默認的導航屬性背後的窗簾過濾器指定一個過濾器。讓我們知道如何解決。