gpt4 book ai didi

c# - Azure SQL DB 保持连接直到 EF 超时

转载 作者:行者123 更新时间:2023-12-03 02:19:05 26 4
gpt4 key购买 nike

我遇到一个间歇性问题,我似乎无法弄清楚 .NET Framework 4.6 MVC API (C#) 使用 Entity Framework 6(运行时 v4.0.30319)存储过程调用需要很长时间做出回应。

存储过程托管在 Azure SQL DB 上。

这是一个不起眼的程序,它会询问几个表格,为营养师提供其客户的最新数据和网站交互。

ALTER PROCEDURE [PORTAL].[GetNutritionistCustomers]

@id_usernut varchar(20)

AS

WITH Activity AS (
SELECT LastActivity = MAX(ExecutionDate),
ded.UserName
FROM portal.DailyExecutionData ded
WHERE ded.ExecutionDate < GETDATE()
GROUP BY ded.UserName
),
Logging AS (
SELECT LastLogin = MAX(l.LoggedOnDate),
l.UserName
FROM PORTAL.Logins l
WHERE l.LoginType = 'Direct Client'
GROUP BY l.UserName
)
SELECT unc.CompanyCode,
a.ACCOUNT,
ad.ADDRESS1,
un.ID_UserNut,
ueu.ExpirationDate,
Expired = CAST(CASE WHEN ueu.ExpirationDate < GETDATE() THEN 1 ELSE 0 END AS BIT),
LastActive = la.LastActivity,
l.LastLogin
FROM UK_Nutritionist un
JOIN UK_NutCompany unc ON un.ID_UserNut = unc.ID_UserNut
JOIN UK_EnabledUsers ueu ON unc.CompanyCode = ueu.UserName
JOIN Klogix.ACCOUNT a ON ueu.ID_User = a.ACCOUNTID
LEFT JOIN Klogix.ADDRESS ad ON a.ADDRESSID = ad.ADDRESSID AND ad.IsPrimary = 1
LEFT JOIN Activity la ON ueu.UserName = la.UserName
LEFT JOIN Logging l ON ueu.UserName = l.UserName
WHERE un.ID_UserNut = @id_usernut

在 SSMS 或 ADS 中运行此过程平均需要大约 50-100 毫秒才能完成。这是一致的,表有很好的索引,并且查询计划都是索引查找。没有 key 或 RID 查找危险信号。

通过分析器进行调查后,我确定发生的情况是 EF 创建连接,调用该过程。可以看到进入了 RPC,EF 达到了连接超时时间,然后 RPC 完成,数据返回到 EF,代码旋转出一个 Pocs 列表以 json 形式返回给调用者。

[HttpGet]
[Route("Customers")]
public HttpResponseMessage Get()
{
try
{
if (IsTokenInvalid(Request))
return Request.CreateResponse(HttpStatusCode.Unauthorized);

var nutritionistCustomers = new ExcdbEntities().GetNutritionistCustomers(TokenPayload.Nutritionist).Select(x => new NutritionistCustomers()
{
Account = x.ACCOUNT,
Address = x.ADDRESS1,
CompanyCode = x.CompanyCode,
ExpirationDate = x.ExpirationDate,
expired = x.Expired,
LastActive = x.LastActive,
LastLogin = x.LastLogin

}).ToList();
return Request.CreateResponse(HttpStatusCode.OK, GenerateResponse(nutritionistCustomers))
}
catch (Exception e)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, GenerateResponse(e));
}
}

如果我更改连接超时,则 SQL 在释放数据之前等待的时间也会发生变化。

我认为这可能与托管 API 的 Azure 应用服务有关,但事实证明,在 Visual Studio 中调试运行它也存在同样的问题。

短期修复是重新编译存储过程。然后,这将立即返回数据。但在未来某个不确定的时刻,相同的过程会突然再次表现出这种行为。

只有这个过程可以做到这一点,所有其他 EF 交互,无论是 linq to sql 表还是 View 询问,以及所有其他过程似乎都表现良好。这种情况以前在具有相同架构的遗留系统中发生过,尽管它是在不同数据库上的不同过程。

虽然缩短超时是一种解决方法,但它是一个系统范围的值,即使足以应对系统故障的 10 秒,对于这个应该是瞬时的客户选择屏幕来说也太长了。另外,如果有人知道可能发生的情况,我宁愿解决根本问题。

我已经考虑过对该语句使用 OPTION_RECOMPILE,但感觉这样做是错误的。

如果其他人经历过这种情况并且有任何见解,我将非常感激,因为它让我分心。

最佳答案

最终证明这是一个串联问题。EF 将 CONCAT_NULL_YIELDS_NULL 设置为关闭其上下文,无论出于何种原因,这都会导致真正可怕的性能问题。

对于我只能称之为无能的前员工的遗留问题,程序返回的日期对日期的各个日期部分进行了一些莫名其妙的切割和串联。

我用返回日期(并且显然修改了 EF 对象)来替换它,嘿,很快就不再有性能问题了。

关于c# - Azure SQL DB 保持连接直到 EF 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69756963/

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