即使“执行后忽略结果”,什么也会导致 SELECT 语句执行延迟和高 ASYNC_NETWORK_IO

Edw*_*and 2 sql-server waits sql-server-2017 query-performance

我们的 SQL Server 面临性能问题。

7 台服务器,都运行相同的应用程序,都存在相同的问题。

SELECT @@VERSION
Microsoft SQL Server 2017 (RTM-CU19) (KB4535007) - 14.0.3281.6 (X64)   Jan 23 2020 21:00:04   Copyright (C) 2017 Microsoft Corporation  Standard Edition (64-bit) on Windows Server 2019 Standard 10.0 <X64> (Build 17763: ) (Hypervisor) 
Run Code Online (Sandbox Code Playgroud)

当您查看累积的服务器总等待统计信息时,会显示 99% ASYNC_NETWORK_IO。我们首先假设这是由应用程序引起的。然而:

当我们获取查询(从应用程序捕获)并从 SSMS 中将其作为测试运行时,执行后忽略结果。当我们通过 TCP 连接运行它时,大约需要 6 秒,通过命名管道连接运行它大约需要 50 秒。我们得到的结果非常慢。

(不考虑执行后的结果,查询给出的结果为 57k 行 227 列,大小为 221MB。)

它是核心版本,因此我们无法使用本地连接。我们测试了使用 TCP 和命名管道进行远程连接。

通过 TCP

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 4 ms, elapsed time = 4 ms.

(57844 rows affected)
Table 'STORE-CUW01$Item'. Scan count 1, logical reads 14774, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 1359 ms,  elapsed time = 6868 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

因此,尽管聚集索引扫描只需要 0.62 秒即可完成,但即使检查执行后忽略结果,仍需要 6.8 秒才能完成查询

命名管道

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

(57844 rows affected)
Table 'STORE-CUW01$Item'. Scan count 1, logical reads 14774, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 1578 ms,  elapsed time = 54202 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

对于命名管道,情况甚至更糟。同样,聚集索引扫描只需要半秒即可完成,而查询则需要 54 秒才能完成。

如果我将数据库恢复到笔记本电脑并运行相同的查询,则聚集索引扫描需要 0.4 秒,CPU 时间为 1375 毫秒,运行时间为 1462 毫秒。

通过使用https://www.sqlskills.com/blogs/paul/capturing-wait-stats-for-a-single-operation/

我收集了 TCP 连接和命名管道连接测试的等待统计信息:

传输控制协议

在此输入图像描述

命名管道

在此输入图像描述

等待时间并不等于总运行时间。在 tcp 测试中,等待时间仅为 0.472 秒,经过时间为 6.8 秒;在 Naped Pipe 测试中,等待时间仅为 40.7 秒,而经过时间为 54.2 秒。

进一步的相关信息

  • SQL Server 是虚拟服务器 VMware
  • 这是Windows核心版本
  • 4核
  • 64GB RAM,仅分配给 SQL Server 16 GB
  • 应用程序服务与 SQL Server 运行在同一台服务器上
  • 应用程序本身与 MARS 会话连接

我们不明白时间延迟从何而来。如果您检查了丢弃结果,查询不是应该更快完成吗?

Dan*_*man 5

结果仍会通过丢弃结果选项返回给客户端。ASYNC_NETWORK_IO丢弃结果的较长等待时间表明返回 221MB 数据的网络延迟。我建议您将故障排除重点放在网络而不是查询计划上。

通过将 200MB 文件从 SQL 计算机复制到客户端来尝试进行简单测试,看看是否获得相似的时间。

  • 尝试使用 sys.dm_exec_session_wait_stats 而不是 XEvents。 (3认同)