2012-09-21 30 views
3

我有一個項目使用EF4(System.Data.Entities,沒有nuget包)並直接命中LINQ查詢的上下文。每當我通過多個用戶登錄進行負載測試(使用VS測試負載測試)時,我的性能表現非常糟糕,我的CPU速度達到100%,VS.NET在高鎖定爭用和高垃圾收集方面拋出警報。使用EF4在ToList()上高鎖爭用和性能下降

在進行大量的分析和調整時,一切似乎都指向了LINQ查詢本身的執行(預計會在某種程度上)以及我們所做的.ToList()調用上令人難以置信的爭用量在結果的一堆地方。

有沒有人遇到過這個?原因是什麼?如何解決這個問題?我是否需要出於某種原因調出.ToList()調用?

更新: 有幾個人要求瞭解更多細節..這裏是代碼有問題(調整了一下,刪除我不能釋放的東西)。

var query = 
      from f in context.fs 
      where f.usr.Any((u) => u.id == id) 
      select new 
      { 
       FS = f, 
       f.fList, 
       E = from e in f.fList select new { e.er }, 
       L = from l in f.fList select new { l.id } 
      }; 
    var res = query.ToList(); 

在重負載下此相同的代碼在多個線程中運行(探查說13)。 ToList()調用是絕對謀殺,並且幾乎涵蓋了所有的延遲。

+0

你能提供一些關於查詢的更多信息嗎?我們在談論多少登錄? –

+0

你有性能分析器嗎?它應該確切地告訴你哪個鎖導致問題。它可能與EF本身完全無關,因爲例如用於查詢的'Expression'類也可能導致鎖爭用。其處理內部使用鎖定靜態字段來控制對某些緩存的訪問。 –

+0

顯示.ToList()調用的代碼以及它們被調用的頻率或位置將會很有用。 – Josh

回答

0

要查詢:如果你需要執行查詢全fList實體進行投影到EL後:

var query = from f in context.fs 
      where f.usr.Any((u) => u.id == id) 
      select new 
      { 
       FS = f, 
       f.fList 
      }; 
var res = query.ToList(); 
foreach (var x in res) 
{ 
    // runs in memory 
    var E = from e in x.fList select new e.er; 
    var L = from l in x.fList select new l.id; 
    // ... 
} 

如果您只需要E和L結合他們:

var query = from f in context.fs 
      where f.usr.Any((u) => u.id == id) 
      select new 
      { 
       FS = f, 
       EL = from x in f.fList select new { e.er, l.id } 
      }; 
var res = query.ToList(); 
+0

工作就像一個魅力!謝謝!! – XeroxDucati

2

您需要記住的是,IQueryableIEnumerable方法使用不同的執行方式。特別是,方法通常不會修改內存中的表達式樹。從探查者的角度來看,他們永遠不會佔用大量的時間。直到ToList調用查詢(從先前的IQueryable方法中生成)才被實際執行,這意味着這是實際網絡IO發生的地方。花費在那個時間上的時間將是顯着高於所有的查詢生成放在一起。

簡而言之,分析器在這裏並不真正幫助你。所有這些工作都通過ToList進行,但確定查詢效率的代碼基本上都是其他地方。有可能你想要的東西本質上是一個昂貴的操作,或者你沒有有效地編寫查詢(在這種情況下,我們需要更多地瞭解它以提供信息)。

至於是否將其並行化會有所幫助,那還不是真的知道。我的猜測可能不是。如果你的CPU最大化,那麼你會保持忙碌,而線程只會增加更多的開銷並減慢你的速度。如果CPU沒有被分配任務,但速度很慢,那麼線程更有可能幫助你。

+0

有道理..但EFprof告訴我,查詢只需要500ms返回,它不是一個龐大的數據集,只有幾個領域..任何方式來調整模型或東西,以提高性能? – XeroxDucati

+0

@XeroxDucati您還沒有收錄足夠的信息來嘗試回答。 – Servy

+0

按要求添加代碼! – XeroxDucati