文章目录
- 客户端应用程序出现问题
- 网络问题
ASYNC_NETWORK_IO 是一种经常被DBA看到的等待类型,当其数值过高时可能会让人担忧,因为这是最难解决的等待类型之一。
需要知道的是,从 SQL Server 2005 开始,这种等待类型被命名为 ASYNC_NETWORK_IO,而在 SQL Server 2000 中,这种等待类型称为 NETWORKIO。这一等待类型的原始名称源自 10M和 100 M慢速以太网速度的时代,这些速度通常在 2000 年代中期之前广泛使用。
大多数情况下,该等待类型的过高数值实际上与网路问题无关(或这是一个非常罕见的情况),尤其是在如今 40Gb、100Gb 的超高速以太网时代,甚至目前正在开发的 200Gb 和 400Gb 速度的网络中。
ASYNC_NETWORK_IO 等待过高可能发生在以下两种情况下:
- 客户端应用程序需要处理从 SQL Server 接收到的数据,然后才能向 SQL Server 发送信号,表示它可以接受新数据进行处理。这是一种常见的情况,通常反映出应用程序设计不佳,这也是导致 ASYNC_NETWORK_IO 等待过高的最常见原因。
- 网路带宽已达到极限。一个拥堵的以太网将导致应用程序之间数据传输变慢,从而降低应用程序的效率。
客户端应用程序出现问题
SQL Server 中 ASYNC_NETWORK_IO 等待类型过高的最常见原因是应用程序无法快速处理从 SQL Server 接收的数据。当应用程序请求大量数据结果集时,缓慢的数据处理会导致数据缓冲区被填满,从而阻止 SQL Server 向客户端发送新数据。「逐行痛苦处理」(Row by Agonizing Row,简称 RBAR)往往是导致此类行为和高 ASYNC_NETWORK_IO 等待类型的原因。在 RBAR 应用程序编程中,每次只处理 SQL Server 发送的结果集中一行数据。在这种情况下,可处理的完整结果集会被缓存,然后通知 SQL Server 该数据集已经「处理完毕」。这将允许 SQL Server 在应用程序处理缓存的结果集数据时发送新的数据集。
当使用 RBAR 处理的应用程序必须处理非常大的数据库环境 (VLDB) 时,往往会遇到数据处理问题。执行批处理的伺服器进程(SPID)将被迫等待,直到应用程序开始处理缓冲区中的数据,这样 SQL Server 才能通过缓冲区将新的结果集发送到客户端。在等待将应用程序请求的新数据发送到缓冲区进行进一步处理的过程中,会产生 ASYNC_NETWORK_IO 等待类型。
当 SQL Server 上出现高 ASYNC_NETWORK_IO 等待类型值时,DBA 应该调查导致过高 ASYNC_NETWORK_IO 等待类型值的应用程序,通常还需要与开发该应用程序的开发人员进行协调。在调查高 ASYNC_NETWORK_IO 等待类型值时,应检查以下内容:
- 检查应用程序是否请求了来自 SQL Server 实例的大量数据集,然后在客户端对这些数据进行过滤。特别要留意诸如 Microsoft Access 或 ORM 软件(对象关系映射)之类的第三方应用程序,它们可能请求了大量数据集并在客户端进行过滤。使用“立即读取,之后处理”的编程方法,通常可以避免出现过高的 ASYNC_NETWORK_IO 等待类型值。
- 确保为客户端应用程序创建了适当的视图,以确保数据过滤在 SQL Server 实例上完成,从而显著减少传输到客户端应用程序的数据量。
- 确保应用程序正在提交已打开的事务,并且及时提交它们。
- 检查是否可以通过直接在 SQL Server 上进行数据过滤来减少请求的数据集。
- 对于个别或临时查询,确保尽可能添加 WHERE 子句,并适当优化查询以限制请求的数据集只包含所需的数据。
检查是否可以在查询中使用“TOP n”以减少查询返回的行数。
标量值用户定义函数(UDF)由于逐行处理(RBAR)通常是导致高 ASYNC_NETWORK_IO 等待类型的原因,因此要查找这些影响性能的对象实例。
使用带有用户定义函数(UDF)的计算列并在大数据库中使用,通常也是由于 RBAR 导致高 ASYNC_NETWORK_IO 等待类型的原因。
在 SQL Server 2016 中,可以使用本机编译的 UDF(用户自定义函数),通常可以显著减少 RBAR 并将执行速度提高多达 100%。这在无法将 UDF 重构为table-valued(表值)函数的情况下特别有用。
注意: SQL Server Management Studio (SSMS) 是一个恶名昭彰的客户端应用程式,因为它会产生大量ASYNC_NETWORK_IO 等待类型。SSMS 以逐行的方式读取资料流,并在处理每一行后才检索下一行。
此外,当在处理 SQL Server 上的大量数据加载过程中,遇到过度的 ASYNC_NETWORK_IO 等待时,也可以通过直接调整 SQL Server 来进行一些其他操作:
- 如果尚未启用,为该 SQL Server 实例启用 Shared memory protocol 。
使用以下查询来确定当前连接使用的协议:
SELECT net_transport
FROM sys.dm_exec_connections
WHERE session_id = @@SPID;
- 確保客戶端使用 net_transport=‘Shared memory’ 進行連接。
如果以上所有检查都完成,但 SQL Server 仍然受到高 ASYNC_NETWORK_IO 等待值的影响,那么就该检查可能导致这种行为的网络相关问题了。这些问题通常由物理网络的限制、故障或仅仅是错误的网络设置引起。为了排除网络引起的 ASYNC_NETWORK_IO 等待,应仔细检查以下内容。
网络问题
- 检查 SQL Server 和客户端之间的网络带宽。网络适配器速度慢且带宽与客户端应处理的数据量不匹配,通常是造成高 ASYNC_NETWORK_IO 等待值的常见原因。100 兆位的适配器仍然存在,并且通常无法满足现代 SQL Server 数据库和处理数据的需求。即使切换到 1 千兆位适配器,对于许多环境来说,系统仍然达不到当前的要求。使用 10 千兆位网络适配器被认为是大多数环境的最低标准,而 200 千兆位和 400 千兆位是许多企业在不久的将来必须切换的标准,如果他们还没有这么做的话。
- 检查每秒批量请求(Batch requests per second)的计数器值,因为这通常可以表明高 ASYNC_NETWORK_IO 等待的原因。在检查批量请求时,需要检查的是 SQL Server 处理的 T-SQL 批量数量,因为这将决定 SQL Server 每秒处理的批量数量。每秒批量请求值超过 1000 的服务器被认为是“繁忙”的。建议的值会依赖于实际的系统配置、活动水平和处理的事务数量。在高峰时段,这个值显著增加并不罕见。
当每秒批量请求(Batch requests per second)的计数器值接近或超过 3,000 并且使用的是 100 兆位网络时,这几乎可以肯定地表明网络速度是瓶颈,并导致高 ASYNC_NETWORK_IO 等待值。如今的服务器每秒轻松处理超过 20,000 批量请求,因此考虑将 1 千兆位或更低的网络升级到 10 千兆位,以满足 SQL Server 数据处理日益增长的需求是明智的选择。 - 检查网卡(NIC)带宽利用率是明智的,但经常被忽视。
使用 Perfmon 工具,可以通过以下公式轻松计算网络利用率:
Network utilization %= ((Total Bytes\Sec * 8)/current bandwidth) * 100
如果利用率的数值经常超过 60%,那么建议切换到更快的网卡或提高网络带宽,以确保在需要时能够分配足够的带宽来进行数据处理。 - 确保网卡的自动协商功能正确检测到网络带宽。
要检查所有活动网络连接的当前速度,可以使用以下命令行命令。
Get-WmiObject -namespace "root\cimv2" -query 'select * from Win32_NetworkAdapter'| Where-Object { $_.NetEnabled -eq $true } | Select-Object Name, Speed
output:
Name Speed
---- -----
Hyper-V Virtual Ethernet Adapter 10000000000
Realtek PCIe GBE Family Controller 1000000000
Npcap Loopback Adapter 1215752192
Microsoft KM-TEST Loopback Adapter 1215752192
Hyper-V Virtual Ethernet Adapter #2 10000000000
Hyper-V Virtual Ethernet Adapter #3 10000000000
Hyper-V Virtual Ethernet Adapter #4 10000000000
VirtualBox Host-Only Ethernet Adapter 1000000000
Hyper-V Virtual Ethernet Adapter #5 10000000000
如果特定适配器的自动协商未选择正确的网络速度,则可以在 NIS 属性中手动设置 NIC 速度