gpt4 book ai didi

c# - 使用 Entity Framework 的简单请求的大量执行时间

转载 作者:行者123 更新时间:2023-11-30 16:38:49 25 4
gpt4 key购买 nike

我在 Entity Framework 6 中有一个奇怪的行为。我有一个简单的(一个简单的 where 和一个简单的选择)查询,它需要 30 秒。

我使用 Sql Profiler 来观察执行了哪些 sql 代码。我正在使用 Where 然后是 FirstOrDefault 方法来获取项目。然后我尝试了另一个查询,我做了一个 ToList(以获取数据),然后是 FirstOrDefault,它只用了不到 1 秒。

Original code (takes 30s to be executed):
-----------------------------------------

id = Container.SocialNetworks.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId).Select(i => i.UserID).FirstOrDefault();

From SQL Profiler :
-------------------

exec sp_executesql N'SELECT
[Limit1].[UserID] AS [UserID]
FROM ( SELECT TOP (1)
[Extent1].[UserID] AS [UserID]
FROM [dbo].[SocialNetworks] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[ID]
WHERE (0 = [Extent1].[SocialNetwork]) AND (([Extent1].[Link] = @p__linq__0) OR (([Extent1].[Link] IS NULL) AND (@p__linq__0 IS NULL))) AND ([Extent2].[TenantID] = @p__linq__1)
) AS [Limit1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 int',@p__linq__0=N'linkedin.com/in/a-profile',@p__linq__1=5

After testing another solutions (takes less than 1s):
-----------------------------------------------------

id = Container.SocialNetworks.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId).Select(i => i.UserID).ToList().FirstOrDefault();

From SQL Profiler:
------------------

exec sp_executesql N'SELECT
[Extent1].[UserID] AS [UserID]
FROM [dbo].[SocialNetworks] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[ID]
WHERE (0 = [Extent1].[SocialNetwork]) AND (([Extent1].[Link] = @p__linq__0) OR (([Extent1].[Link] IS NULL) AND (@p__linq__0 IS NULL))) AND ([Extent2].[TenantID] = @p__linq__1)',N'@p__linq__0 nvarchar(4000),@p__linq__1 int',@p__linq__0=N'linkedin.com/in/a-profile-as',@p__linq__1=5

如您所见,我使用 ToList 在使用 FirstOrDefault 进行过滤之前获取数据。而且,通常情况下,不建议执行 ToList,即急切加载。为什么在我使用 FirstOrDefault 时 Entity Framework 将一个 select 放入一个 select 中?

我很抱歉我的英语不好,我希望我能正确解释我的问题。

编辑:

我有一些有趣的事情要补充,当“linkedinurl”值不存在时,并且只有当它不存在时,在数据库中,两个查询都不到 1 秒。

编辑 2:

写完评论后,我想补充一点,我们的数据库在 Azure 上。并且这个问题不会出现在一个简单的SQLEXPRESS 数据库上。而且,这个问题似乎是四五天前出现的。

最佳答案

那是因为您在 where().Select() 组合之后使用了 FirstOrDefault

第一个查询会像这样工作得更好:

id = Container.SocialNetworks.FirstOrDefault(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId)?.UserID;

如您所见,我使用 FirstOrDefault 就像您使用 Where 一样,但这将加载整个对象,如评论中所述。

为什么你的二次查询更快?因为您使用 ToList() 结束了查询,所以 FirstOrDefault 部分仅在您的 c# 代码中应用,在加载行之后,而不是在具有双重选择的 DB 上.

编辑:

尝试这两行可能会更好地突出根本原因:

<强>1。尝试订购您的套装:

id = Container.SocialNetworks
.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId)
.OrderBy(t => t.UserID).Select(i => i.UserID).FirstOrDefault();

<强>2。使用聚合函数:

id = Container.SocialNetworks
.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId)
.Min(i => i.UserID);

关于c# - 使用 Entity Framework 的简单请求的大量执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54329292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com