Azure SQL 数据库挂起连接直到 EF 超时

Azure SQL DB hanging on to connection until EF times out

我有一个间歇性问题,我似乎无法深入了解 .NET Framework 4.6 MVC API (C#) 使用 Entity Framework 6(运行时 v4.0.30319 ) 需要很长时间才能响应的存储过程调用。

存储过程托管在 Azure SQL 数据库上。

这是一个不起眼的程序,它会询问几个 table 以向营养师提供他们客户的最新数据和网站互动。

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 毫秒才能完成。这是一致的,tables 有很好的索引,查询计划都是索引查找。没有密钥或 RID 查找危险信号。

在使用探查器进行调查后,我确定发生的事情是 EF 创建连接,调用过程。我可以看到 RPC 进入,EF 达到连接超时时间,然后我们完成 RPC,数据 returns 到 EF,代码旋转出一个 pocs 列表到 return 到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 中的调试中有同样的问题.

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

只有这个程序执行此操作,所有其他 EF 交互,无论是 sql table 的 linq 还是查看询问,所有其他程序似乎都表现良好。 这种情况以前在具有相同体系结构的现在遗留系统中发生过,尽管它是不同数据库上的不同过程。

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

我考虑过OPTION_RECOMPILE声明,但感觉这样做不对。

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

最后证明这是一个连接问题。 EF 将 CONCAT_NULL_YIELDS_NULL 设置为关闭 inits 上下文,无论出于何种原因,这都会导致真正糟糕的性能问题。

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

我将其替换为,您知道,返回日期(显然修改了 EF 对象),嘿,很快就没有性能问题了。