为什么读懂执行计划对你是那么重要

一条俊俏的 SQL 被一个懵懂的少年,扔向了深远的 TCP 隧道,少年苦苦等待,却迟迟等不来那满载而归。于是少年气愤,费尽苦心从度娘那边求来的一手好代码,等来的却是 timeout…

如果你也正在经历着这些苦涩的等待,那么该了解执行计划了;如果你自认为执行计划已经了如指掌,那么你该读一读 SQL Server 2017 新特性, adaptive query processing , 我蹩脚的将其翻译为 “自适应查询处理”。

在讲解概念之前,首先要对内存分配要有清晰的理解。一个查询请求在执行完毕之后,会有详细的内存分配指标和统计值附加在它的执行计划属性上。这些内存分配指标和统计值,分别是执行前预估的内存分配和最佳内存大小以及运行中被分配的内存大小。

如果一开始内存预估分配不准确,在执行的时候,就会分配不到合理的执行内存,导致整个查询期间,频繁的往 tempdb 里面去做spill(这个词真不好翻译,有缓存溢出的意思,即内存装不下,暂交给 tempdb 存储的意思), 将不能被当前内存空间容纳的数据缓存到 tempdb 里面,利用硬盘IO来缓存数据,比起内存存储效率差了很多。因此在执行前就需要保证预估的数据量大小和需要的内存比较精确。 这里需要对统计信息 (statistics)做实时更新,以便预分配内存准确。

Brentozar 有个实例可以很好的解释和解决这个问题:
https://www.brentozar.com/blitzcache/tempdb-spills/

换句话来说,对即将执行的查询,分配足够多的内存,那么该查询的执行所需的数据,就完全可以在内存中处理,而不会溢出到硬盘。从而查询速度就快。

如果发生 spill 会有系统提示,这必须依靠执行计划才能铺捉到

为什么读懂执行计划对你是那么重要_第1张图片

在 SQL Server 2017 出来之前,需要掌握 DBA 知识才能意识和掌握处理这类事情。但 SQL Server 2017 之后,作为普通的一名开发者,完全可以忽略这类问题,因为 adaptive query processing 已经帮我们在幕后优化这类 SQL.

如上所说,SQL 执行完毕之后,会将执行计划与执行环境( execution context)一起缓存。Adaptive Query Processing 引入了 Batch Mode memory grant
feedback. 执行引擎通过对执行计划缓存属性的校验,可以发现请求的执行过程中,是否发生了 spill,对于发生 spill 的情况,引擎会对这份执行计划做重估,一旦发现如统计信息过期 等导致的 spill, 就会用最新的统计信息去重估执行计划,更新执行计划中分配内存的策略,要么降低内存分配提高并发中内存需要,要么提高内存,减少 spill 的发生概率。这些校验都回反馈给 memory grant feedback, 由 它采用最新的策略,去更新执行计划缓存。

上述讲的是自适应查询处理( Adaptive Query Processing)中 Batch Mode Memory Grant Feedback 的一个自动处理特性,被称为 memory grant feedback sizing. 除此之外,SQL Server 2017 还带来了更多的智能优化策略, 自动化完成 DBA 的部分工作。

为什么读懂执行计划对你是那么重要_第2张图片

你可能感兴趣的:(sql,server,SQL,Server,实战笔记)