我们有一个REST服务来获取一个ID的成员。 SQL运行速度很快(5ms)但是从Linq运行时(使用Entity框架6),运行速度非常慢(230ms)。
我不认为这个问题与this,this或this重复,因为感觉Linq / EntityFramework相关。
以下是统计数据: 客户端呼叫成员获取所花费的时间约为360毫秒 从C#代码执行Linq查询所花费的时间约为230毫秒 在SQL Server上执行SQL所需的时间约为228毫秒
生产中的SQL跟踪具有类似的性能(在SQL服务器上执行SQL需要141ms),因此数字感觉真实。
我尝试连续六次运行Linq查询,看看是否可能从datacontext建立连接的成本是个问题。每个Linq查询都花费相同的时间来运行。
如果我使用相同的datacontext直接运行SQL(即:Linq生成的内容),则运行时(从C#开始测量)从230ms降至19ms。
直接在服务器(SQL Server管理工作室)上运行SQL大约需要5毫秒。
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
答案 0 :(得分:0)
经过一番调查,我发现了问题。数据库对其所有字符串使用varchars。当Linq将其参数传递给SQL Server时,它将它们作为Unicode传递。 SQL Server查看数据类型并确定它不能使用varchar索引,因此回退到线性扫描。
通过将我的数据库从varchar更改为nvarchar,我的查询速度从258毫秒变为3毫秒。