设想
我运行一个长而复杂的查询,在 SSMS 中返回 30 多个字段和 77,000 多行。结果到网格。结果都是以文本为主。SSMS 网格在几秒 (3 - 4) 秒后开始填充结果,但查询执行时间为 2 分钟。这 2 分钟的大部分时间都是附加到 SSMS 网格中的结果。
问题)
查询什么时候“完成”?当行开始追加到 SSMS 网格时,它是在前 3 - 4 秒内完成的吗?剩下的 1 分 56 秒只是网格 UI 更新结果吗?如果查询在 3 - 4 秒后“完成”,那么我不应该考虑优化它,对吗?相反,如果查询直到 SSMS 中停止执行(整整两分钟)才完成,那么我应该能够考虑优化它?
当客户端从服务器收到最后一个查询结果包时完成。
如果客户端消耗结果的速度很慢,那么这将延迟整个查询的执行,并且它将被挂起等待
ASYNC_NETWORK_IO
。查询不会运行到完成并将结果缓冲到某处然后才发送它们。因此,3-4 秒后看到一些结果并不表明查询已“完成”。
例如,我在 SSMS 中运行了以下命令,同时启用了“实时查询统计”和“实际执行计划”。
结果或多或少立即开始出现在网格中。
当它完成时,实际执行计划中的查询时间统计信息显示了毫秒的运行时间,
80,668
同一计划中的等待统计信息显示了60,184
毫秒的ASYNC_NETWORK_IO
等待时间在运行时查看实时执行计划表明行仍然从执行计划运算符一直流到最后(例如,下面是我一分钟后的情况,此时它已返回 16,393 行)
如果上述查询在隔离级别上运行,要求它持有锁直到语句结束,那么这将意味着由于客户端速度慢,锁保持打开的时间更长。
上面的查询没有“阻塞”运算符,因此在上面的情况下,行或多或少立即开始流向客户端。
有关此内容的更多信息,您可以查看有关“查询结果何时开始”的相关但相反的问题
另一件需要注意的好事情(因为您在性能调整方面提出这个问题)是您可以丢弃 SSMS 中的查询结果。这样做将帮助您更准确地了解查询的运行时(不包括消费者/客户端的渲染时间等)。当我对查询本身执行的运行时更感兴趣时,我通常会打开此功能: