Sql 为什么我的实体框架查询与单个查询比较慢?

Sql 为什么我的实体框架查询与单个查询比较慢?,sql,sql-server,performance,entity-framework,database-performance,Sql,Sql Server,Performance,Entity Framework,Database Performance,我有一个非常简单的查询,速度非常慢。实体框架探查器说,大约需要100毫秒 dbContext.Users.Single(u => u.Id == userId); 在尝试了一下之后,我发现了一个非常相似但速度更快的查询(大约3毫秒) 当我比较两个查询的sql时,第二个查询没有使用嵌套的SELECT和NOTOP操作。但我不希望仅仅因为这两件事,它会快30倍。另外,在使用SQLServerManagementStudio执行查询时,没有任何差异 当我查看执行计划时,它们都会进行聚集索引查找,

我有一个非常简单的查询,速度非常慢。实体框架探查器说,大约需要100毫秒

dbContext.Users.Single(u => u.Id == userId);
在尝试了一下之后,我发现了一个非常相似但速度更快的查询(大约3毫秒)

当我比较两个查询的sql时,第二个查询没有使用嵌套的SELECT和NOTOP操作。但我不希望仅仅因为这两件事,它会快30倍。另外,在使用SQLServerManagementStudio执行查询时,没有任何差异

当我查看执行计划时,它们都会进行聚集索引查找,这具有100%的查询成本。而额外的select和Top操作的查询成本为0%。 来自EFProfiler的查询计划也是如此,这表明它不应该有任何区别

在这种情况下,如何更好地了解查询性能

下面是第一个查询的结果SQL

SELECT [Limit1].[Id]                     AS [Id],
   [Limit1].[EmailAddress]           AS [EmailAddress],
   [Limit1].[FirstName]              AS [FirstName],
   [Limit1].[LastName]               AS [LastName]
FROM   (SELECT TOP (2) [Extent1].[Id]                     AS [Id],
                   [Extent1].[EmailAddress]           AS [EmailAddress],
                   [Extent1].[FirstName]              AS [FirstName],
                   [Extent1].[LastName]               AS [LastName]
    FROM   [dbo].[Users] AS [Extent1]
    WHERE  ([Extent1].[Id] = 'b5604f88-3e18-42a5-a45e-c66cc2a632d3' /* @p__linq__0 */)
           AND ('b5604f88-3e18-42a5-a45e-c66cc2a632d3' /* @p__linq__0 */ IS NOT NULL))    AS [Limit1]
这里是第二个(更快)查询的sql

当你说

dbContext.Users.Single(u=>u.Id==userId)

用户的类型为DbSet或其用户集合,因此在
dbContext.Users.Where(u=>u.Id==userId.ToList().Single()
它包含加载它的条件

所以如果有100个用户 第一个查询将获取100个用户,然后进行过滤,而第二个查询只获取1个用户


希望这有帮助。

您真正想要的是
dbContext.Users.Find(id)
-如果不需要,它甚至不会进入数据库。有关的详细信息,请参见。

在第二个示例中,您还可以省略
ToList()
调用
Single()
还枚举查询。只需保留
Where()
子句..Single()需要返回“top 2”结果以确定是否存在单个匹配项。结果中的一行表示成功,两行或零行表示“.Single()”失败,应引发错误。在第二个示例中,“.ToList()”导致在应用“.Single()”之前执行查询。查询可以返回任意数量的结果,将对列表结果应用.Single()方法。您是否在同一个应用程序中尝试这两个查询,如果是,则应用程序中第一个查询实体框架生成的两个查询中的速度较慢吗?实体框架对于每个应用程序域每个数据库执行的第一次查询来说是一个非常大的开销,它会重新使用在第一次查询之后构建的缓存元数据,即使对象被释放,但第一次查询的速度会慢得多(只是在程序中第二次运行相同的查询,您将看到速度的显著变化)@Towa我很惊讶GUID上的聚集索引没有降级performance@Jaycee:很可能是这样,但也可能是因为他的表很小,所以页面不会太多,如果有的话…guid的主键不好…+1告诉我Find().我以前不知道。但在这个特殊情况下,它生成的SQL与Single相同,并且具有相同的(坏的)SQLperformance.Anshul,第一个查询将只返回数据库中与该用户ID匹配的前两个用户。它不会获取所有100个用户。即使有100个用户具有该用户ID。第二个查询将返回与该用户ID匹配的所有用户,然后在内存中应用单个方法。为什么不在此处询问您的问题(但不同的线程)关于堆栈溢出?:)
SELECT [Limit1].[Id]                     AS [Id],
   [Limit1].[EmailAddress]           AS [EmailAddress],
   [Limit1].[FirstName]              AS [FirstName],
   [Limit1].[LastName]               AS [LastName]
FROM   (SELECT TOP (2) [Extent1].[Id]                     AS [Id],
                   [Extent1].[EmailAddress]           AS [EmailAddress],
                   [Extent1].[FirstName]              AS [FirstName],
                   [Extent1].[LastName]               AS [LastName]
    FROM   [dbo].[Users] AS [Extent1]
    WHERE  ([Extent1].[Id] = 'b5604f88-3e18-42a5-a45e-c66cc2a632d3' /* @p__linq__0 */)
           AND ('b5604f88-3e18-42a5-a45e-c66cc2a632d3' /* @p__linq__0 */ IS NOT NULL))    AS [Limit1]
SELECT [Extent1].[Id]                     AS [Id],
   [Extent1].[EmailAddress]           AS [EmailAddress],
   [Extent1].[FirstName]              AS [FirstName],
   [Extent1].[LastName]               AS [LastName]
FROM   [dbo].[Users] AS [Extent1]
WHERE  ([Extent1].[Id] = 'b5604f88-3e18-42a5-a45e-c66cc2a632d3' /* @p__linq__0 */)
   AND ('b5604f88-3e18-42a5-a45e-c66cc2a632d3' /* @p__linq__0 */ IS NOT NULL)