Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Linq查询运行缓慢,但查询在隔离状态下运行快速_Performance_Linq_Entity Framework - Fatal编程技术网

Performance Linq查询运行缓慢,但查询在隔离状态下运行快速

Performance Linq查询运行缓慢,但查询在隔离状态下运行快速,performance,linq,entity-framework,Performance,Linq,Entity Framework,我们有一个REST服务来获取给定ID的成员。SQL在隔离状态下运行得很快(5ms),但从Linq运行时(使用实体框架6),它运行得非常慢(230ms) 我不认为这个问题与Linq/EntityFramework重复,也不认为它与Linq/EntityFramework相关 以下是统计数据: 客户端调用成员get所用的时间约为360ms 从C#代码执行Linq查询所需的时间约为230毫秒 在SQL Server上执行SQL所需的时间约为228ms 生产中的SQL跟踪具有类似的性能(在SQL ser

我们有一个REST服务来获取给定ID的成员。SQL在隔离状态下运行得很快(5ms),但从Linq运行时(使用实体框架6),它运行得非常慢(230ms)

我不认为这个问题与Linq/EntityFramework重复,也不认为它与Linq/EntityFramework相关

以下是统计数据: 客户端调用成员get所用的时间约为360ms 从C#代码执行Linq查询所需的时间约为230毫秒 在SQL Server上执行SQL所需的时间约为228ms

生产中的SQL跟踪具有类似的性能(在SQL server上执行SQL需要141ms),因此这些数字是真实的

我连续六次尝试运行Linq查询,看看从datacontext建立连接的成本是否有问题。每个Linq查询运行的时间都相同

如果我使用相同的datacontext直接运行SQL(即:Linq生成的内容),则运行时(从C#开始测量)从230ms下降到19ms

直接在服务器(SQLServerManagementStudio)上运行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

经过更多的调查,我发现了问题。数据库对其所有字符串使用varchars。当Linq将其参数传递给SQL Server时,它将它们作为Unicode进行传递。SQLServer查看数据类型,并认为它不能使用varchar索引,因此退回到线性扫描


通过将我的数据库从varchar更改为nvarchar,我的查询速度从258ms提高到3ms。

不要使用
DateTime。现在
要在500ms以下计时,请使用
秒表
类重新运行测试。另外,您是如何让原始SQL在服务器上运行的?您到底是如何运行它的?最后,如果您使用Sql Profiler,linq查询执行服务器端需要多长时间?@ScottChamberlain-我使用秒表重新运行这些查询。结果在所提供数字的5%以内。SQL是从linq查询(tostring())和SQL跟踪中提取的。直接在management studio中运行查询的运行时间为5ms。在这种情况下,是where子句中的参数导致了此问题,还是返回的行本身就是字符串也导致了此问题?@Gilles-问题在于类型不匹配。只要参数与实际的数据库列类型匹配,就可以了。也就是说,.Net将所有字符串作为unicode传递,因此DB字符串列应始终为nvarchar。如果无法控制DB列的类型,该怎么办?