我有一个在 Azure 中运行的应用程序。它有一个部署为应用服务的 .NET 框架 API,连接到 Microsoft Sql Server。 .NET Framework 应用程序使用 Entity Framework Code First 来访问数据库。
通常,应用程序运行顺利。然而,有时,一个端点会变得无响应(即需要几分钟才能返回答案)。该端点正在通过 EntityFramework 进行查询,并从数据库中检索一些数据点。这是针对 2 到 8 个传感器执行的代码(没有任何区别):
List<Measurement> result = CreateContext().Measurements
.Where(m => m.MeasurementSeries.SensorInfoID == sensorId)
.Where(m => m.MeasurementSeries.StartTime <= toTime && m.MeasurementSeries.EndTime >= fromTime)
.Where(m => m.Time > fromTime && m.Time <= toTime)
.OrderByDescending(m => m.Time)
.ToList();
通过查看指标(也来自 ApplicationInsight),我发现没有执行任何奇怪的查询。我看到了预期的查询,并且数据库计算利用率跃升至 100%。
从相同的代码执行相同的查询,连接到相同的远程数据库,但使用本地运行的 .NET Framework 应用程序,只需不到一秒的时间,并且从数据库进行的计算不到 1%。当查询(最终)完成时,数据库计算利用率将恢复为零。 API 计算利用率始终非常低。直接对数据库执行相同的 SQL 查询只需不到一秒。
所有其他端点(其中一些对数据库进行大量查询)都工作正常。
我尝试从多个源多次重新运行相同的查询、重新启动、停止和启动、重新部署应用程序。什么都没发生。上次,过了半天,就又开始工作了。这次已经一天多了,什么也没有。
您是否有任何指向在哪里查找问题的指示?如果我可以提供更多信息,请告诉我,因为我可能没有考虑过它们,它也可以帮助我解决问题。
最佳答案
感谢@PrebenHuybrechts 在问题的评论中提供了解决该问题的工具。正如建议的,对于像这样的问题,最好检查 locks 、 wait stats and execution plan 。
TL;DR
最大 DOP 设置为无限,并且考虑到我将 Sql Server 作为无服务器运行,并从 2 个 vCore 扩展到 16 个,有时它对于非常小的查询确实会过度并行化。
以下工具对于调试很有用:sp_whoisactive、sp_BlitzWho。
长(呃)版本
首先,我使用 sp_whoisactive 来查看在等待 API 答复时发生了什么。我调用了端点,然后运行
EXEC sp_WhoIsActive
@get_task_info = 2
在结果中,我发现有问题的查询处于挂起状态,wait_info
状态为 CXPACKET
。从 this article 我发现 CXPACKET 意味着主进程正在等待从属进程完成处理,并且 Microsoft 建议将 Max DOP(最大并行度)设置为 8。 I did that 使用 Microsoft SSMS,效果非常好。
我猜测,考虑到在其他地方使用相同的查询来检索更大量的数据,它正在针对该场景对其进行优化,这使得当查询仅检索时速度很慢一些数据点。
关于c# - Azure:.NET Framework(首先使用 EF 代码)和 Microsoft SQL Server 对于某些查询突然出现 CPU 峰值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62890402/