排查ASYNC_NETWORK_IO等待类型导致的慢查询问题

现象

当 SQL Server 生成结果集并通过将结果放入输出缓冲区将其发送到客户端应用程序时,客户端应用程序会从输出缓冲区提取结果集。 如果客户端应用程序停止或未足够快速地提取结果,SQL Server 必须等待确认客户端应用程序已收到所有结果,然后才发送更多结果。 此等待将显示为 ASYNC_NETWORK_IO。 有关详细信息,请参阅在 SQL Server 中了解ASYNC_NETWORK_IO等待的视频

过度ASYNC_NETWORK_IO等待可能会导致两个问题:

  • 查询速度可能会变慢,因为它们的总持续时间会更长。

  • 当 SQL Server 等待客户端提取结果时,它无法释放获取的锁。 如果锁定长时间未释放,则会在 SQL Server 上阻塞其他会话。

原因和解决方法

以下部分列出了此等待类型的常见原因以及解决此问题的相应步骤:

大型结果集

某些应用程序客户端请求数千甚至数百万行,然后通过应用筛选器、排序和聚合来处理结果。 大型结果集可能会导致不必要的网络利用率和客户端应用程序处理。

解决方法: 应用程序开发人员必须仔细平衡 SQL Server 和客户端之间的处理。 筛选或聚合可由 SQL Server 执行,最终结果集可能很小。 限制到达客户端的结果集。 在收到数据后,在客户端上对数据、呈现和格式设置进行更多的计算更合适。

应用程序无法快速提取结果

如果客户端应用程序无法快速提取结果,并且不会通知 SQL Server 已收到结果集,则 ASYNC_NETWORK_IO 等待将在服务器上发生。

为了说明如何使用 ADO.NET,默认情况下, DataSetDataTable 将提取所有行以完成,然后客户端才能访问它。 但是,SqlDataReader类允许应用程序开发人员选择从服务器提取每行后要执行的操作。 应用程序可以一次提取一行,然后根据业务需求处理此行。 例如:

  • 将行写入文件。

  • 通过网络将行发送到另一个应用程序。

  • 等待一段时间或用户输入。

解决方法: 若要解决此问题,请使用紧密的 WHILE/FOR 循环,以尽可能快的速度提取所有结果。 这意味着将结果存储在内存中,然后才执行更多处理。

客户端应用程序计算机承受压力(I/O、内存或 CPU)

即使开发应用程序代码以尽快提取结果,系统资源问题也可能导致整个客户端进程速度缓慢。 例如:

如果运行客户端应用程序的计算机具有资源约束,则应用程序可能无法快速提取结果。 例如:

  • 100% CPU 使用率

  • 内存不足(占用所有内存)

  • I/O 速度缓慢(可能是应用程序写入结果或日志)

这些资源约束可能会导致传入结果的处理速度缓慢,并导致 SQL Server 遇到等待类型 ASYNC_NETWORK_IO

解决方法:若要解决此问题,请使用性能监视器工具诊断运行应用程序的系统,然后消除任何资源约束。 以下方法之一可能适用于你:

  • 阻止其他应用程序运行。

  • 修复这些应用程序中的任何代码问题。

  • 如果应用程序已完全优化,请升级系统上的硬件。

NIC/网络

网络或网络接口卡 (NIC) 缓慢可能会导致网络流量延迟,并且自然会延迟提取结果并与 SQL Server 通信。 网络延迟通常由以下问题引起:

  • 网络适配器驱动程序问题

  • 网络筛选器驱动程序问题

  • 配置错误或防火墙有故障

  • 路由器问题

  • 由于流量导致网络过载(不太常见)

解决方法: 若要诊断这些问题,可以 收集网络跟踪 并查找数据包重置和重新传输。 然后,可以解决与网络相关的问题,以消除数据包重置/重新传输。

另请参阅

sys.dm_os_wait_stats中的ASYNC_NETWORK_IO