测量长距离 SQL 连接的延迟

Mau*_*itz 6 performance sql-server sql-server-2012 query-performance

我们为连接到其 SQLServer 数据库的客户编写了一个简单的“客户端”应用程序,对“属性”运行大约 360 次查询,并将该数据作为我们称为“cProp”的 .Net 对象返回。

查询的复杂性各不相同,但最长的可能需要 400 毫秒。当我们最近为 60 个属性运行它时,整个运行大约需要 3 分钟。客户决定将他们的数据库移动到我们之间 65 毫秒的远程服务器。结果,相同的查询需要 51 分钟。

现在我 99% 确定问题是行检索,但我需要证明这一点。DBA 对该过程进行了跟踪,但之前从未使用过它,我很沮丧地发现它包含的信息如此之少。我所看到的是,它花了不到 4 分钟的服务器时间。这加强了我的信念,即问题出在行检索上。

但我如何衡量呢?跟踪不返回关于行数或总数据大小的任何信息 - 我做错了吗?我也知道批处理发生在服务器之外,那么我们如何知道那里发生了什么?一般来说,可以这么说,如何调试“服务器外部”发生的问题。

Jos*_*ell 6

只是在这里澄清一些数学:

  • 每个“属性”360 次查询
  • 60 个属性 * 360 = 21,600 个查询
  • 3 分钟的持续时间约为每秒 120 个查询

因此,在您最好的情况下,您的平均吞吐量为每秒 120 次查询。

将 SQL Server 移动到 ping 延迟为 65 毫秒的某个地方后,您平均每秒进行 7 次查询。

你最好的选择是

  • 在此查询运行时测量等待统计信息
    • 如果您没有监控工具,一个简单的方法是运行sp_BlitzFirst,这是一个由 Brent Ozar Unlimited 开发的开源工具。它将拍摄您的等待统计数据(以及其他内容)的快照,等待 5 秒,然后再拍摄另一个快照,并向您显示最大问题的摘要
    • 您还可以查看自服务器开始使用类似 Paul Randal 博客文章中的查询以来的等待统计信息:等待统计信息,或者请告诉我哪里有问题
  • 获得这些结果后,检查最高等待统计数据,并使用SQL Skills 等待统计数据库深入了解它们的含义

根据您的描述,您很可能会看到ASYNC_NETWORK_IO waits。这可能表示网络传输缓慢。但通常这意味着客户端应用程序正在逐行处理,而 SQL Server 正在等待发送行(当它真的想尽快通过网络触发它们时)。

在相关说明中 - 通常,尝试提取更大的数据“组”会更有效 - 而不是运行 21,000 次查询,从而在(可能较慢的)网络上进行 21,000 次往返。 这称为“健谈”接口或 API,通常被认为是一种反模式

考虑 65 毫秒 * 21,600 次查询是 1,404,000 毫秒,也就是超过 23 分钟的开销。这是一大块可以通过限制往返次数来消除的偷听。