排查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