我們有一個REST服務來獲取給定ID的成員。 SQL運行速度很快(5ms),但是從Linq運行(使用Entity framework 6)時,運行非常慢(230ms)。Linq查詢運行緩慢,但查詢運行速度很快
我不是這個問題是this,this或this的副本,因爲它感覺與Linq/EntityFramework相關。
這裏是統計: 調用成員GET採取客戶端的時間約爲360ms 從C#代碼執行LINQ查詢所需要的時間約爲230ms 執行的SQL的SQL所花費的時間服務器大約是228ms
生產中的SQL跟蹤具有相似的性能(在SQL服務器上執行SQL爲141ms),因此數字感覺真實。
我試着連續六次運行Linq查詢來查看從datacontext建立連接的成本是否成問題。這些Linq查詢中的每一個都花費了相同的時間來運行。
如果我使用相同的datacontext直接運行SQL(即:Linq生成的),運行時(從C#測量)從230ms下降到19ms。
直接在服務器上運行SQL(SQL Server management Studio)大約需要5ms。
C#代碼(都在同一程序中,使用相同的datacontext,沒有使用塊)產生這些數字:
Linq original query run =227ms
Raw SQL query: 19ms
Linq run 0=228
Linq run 1=227
Linq run 2=229
Linq run 3=229
Linq run 4=232
LINQ查詢看起來像這樣:
DateTime start = DateTime.Now;
var memberDetail = await (from member in DataContext.Members.AsNoTracking()
join memberName in DataContext.MemberNames.AsNoTracking() on member.UID equals memberName.MemberID into nameOutput
from mn in nameOutput.DefaultIfEmpty()
join memberProperty in DataContext.Properties.AsNoTracking() on member.PropertyID equals memberProperty.UID
join membershipCycle in DataContext.MembershipCycleHistories.AsNoTracking() on member.UID equals membershipCycle.MemberID into cycleOutput
from co in cycleOutput.DefaultIfEmpty()
where member.ReferenceNumber.Equals(memberNumber) &&
memberProperty.ExternalID.Equals(property, StringComparison.InvariantCultureIgnoreCase)
select new
{
member.UID,
member.Created,
member.LastUpdated,
PropertyName = memberProperty.ExternalID,
member.ReferenceNumber,
member.Active,
member.IsAwaitingSync,
member.Class,
mn.FirstName,
mn.LastName,
mn.PreferredName,
MembershipCreditBalance = co.MembershipCredits,
member.DOB
}
).FirstOrDefaultAsync();
System.Diagnostics.Trace.WriteLine(String.Format("linq run original={0}", (DateTime.Now - start).TotalMilliseconds));
和連接字符串是:
Data Source=SQLServer123;Initial Catalog=DB123;Persist Security Info=True;User ID=User123;Password=PWD123;MultipleActiveResultSets=True
不要使用'DateTime.Now'在500ms以下執行計時,請使用'Stopwatch'類重新運行測試。另外,您是如何獲得原始SQL針對服務器運行的,您是如何運行它的?最後,如果您使用Sql Profiler,linq查詢需要多長時間才能執行服務器端? – 2015-04-02 00:20:18
@ScottChamberlain - 我用秒錶重溫這些。結果在提供的數字的5%以內。 SQL是從linq查詢(tostring())和SQL跟蹤中提取的。直接在management studio中運行查詢的運行時間爲5毫秒。 – dave 2015-04-02 01:08:54