一文搞定 SQL Server 执行计划

导读

数据开发过程中,开发完成的 SQL 发布到生产环境,经常会发生 SQL 执行慢甚至根本无法执行,如何避免这种情况呢?这一篇我们分析一下 SQL Server 的执行计划是如何生成及如何阅读评估执行计划。

基本概念

在此之前,我们先了解以下几个概念,方便我们理解。

本文中的 SQL 语句案例以及执行计划均使用 SQL Server 2017 版本自带的 AdventureWorksDW 样例数据库。

索引

索引本质上就是一种帮助数据库高效获取数据的数据结构,比如 B 树树索引使用二分查找法查找,检索一条记录的复杂度是 O(LogN)。但是这也不意味着索引越多越好,维护索引同样会影响写入性能,需要根据实际情况平衡数据写入的读写性能。索引是基于数据库表创建的,包含一个表中的某些列的值以及记录对应的地址,并且把这些值存储在一个数据结构中。常见的就是使用哈希表,B+ 树,SQL Server 中使用的就是 B+ 树。SQL Server 提供了如下集中索引类型。

一文搞定 SQL Server 执行计划_第1张图片 索引类型
执行计划

执行计划也称为“查询计划”或者”执行计划“,是 SQL 语句的执行方式,由查询优化器根据数据库中表和索引的定义以及数据库统计信息,为 SQL 语句选择的最高效的数据访问方式,然后交给执行器去执行。

一文搞定 SQL Server 执行计划_第2张图片
执行计划缓存

SQL Server 提供了一个用于存储执行计划和数据缓冲区的内存池,内存池中中用于存储执行计划的部分称为计划缓存。SQL Server 中执行任何 TSQL 语句时,数据库引擎首先查看计划缓存,确认是否存在同一个 TSQL 语句的现有执行计划。SQL Server 会重用找到的任何现有计划,节省重新编译 TSQL 语句的开销。如果没有执行计划,则为查询生成新的执行计划。

既然是缓存,执行计划何时会从缓存中删除呢?当存在内存不足, SQL Server 使用基于开销的方法确定从计划缓存中删除哪些执行计划。如果内存不足,SQL Server 会重复检查执行计划,直至删除了足够多的执行计划。

重新编译执行计划

执行计划会在某些情况下导致无效, SQL Server 检测到使执行计划无效的更改后,将执行计划标记为无效。此后,SQL Server 必须要下一个连接重新编译新的计划。

导致计划无效的情况有:

1),查询引用的表或者视图进行了更改;
2),存储过程的修改;
3),执行计划使用的索引有更改或删除;
4),执行计划使用的统计信息有更新,统计信息可以通过 update statistics 显式生成或者自动生成;
5),执行了 sp_recompile;
6),存储过程使用了 with recompile 选项;

执行计划重用不一定是一件好事,而编译/重编译也不一定是一件坏事。需要根据实际场景来判断是应该重用执行计划还是重编译执行计划。

如何显示执行计划

SSMS 提供了三种用于显示执行计划

1),估计执行计划,是编译的计划,由查询优化器根据估计生成。预估执行计划不等于实际执行计划,但是绝大多数情况下实际的执行计划跟预估执行计划都是一致的。统计信息变更或者执行计划重编译等情况下,可能会造成不同。

一文搞定 SQL Server 执行计划_第3张图片

2),实际执行计划,是编译计划及其执行上下文,在执行 SQL 语句后出现,包括实际运行时信息。

一文搞定 SQL Server 执行计划_第4张图片

3),实时查询统计信息,与实际执行计划相同,包括编译的计划和执行上下文。可用于正在进行的查询执行,每个一秒更新一次。开销有可能比较大,不建议生产环境使用。下图中

一文搞定 SQL Server 执行计划_第5张图片

基本法则

前置条件介绍完,现在正式进入主题。首先是执行计划的阅读方式,我们需要遵循一个基本法则: 自上向下,从右向左。同一行的执行计划步骤,右边的先执行。同一列的执行步骤,上边的先执行。

基本图形

在阅读执行计划之前我们有必要了解以下 SQL Server 图形执行计划中提供的基本图标的意义。

1),并行执行,如果给定的图形执行计划图标包含一个带有两个从右到左箭头的黄色圆圈,则表示运算符并行执行。

一文搞定 SQL Server 执行计划_第6张图片 并行执行

2),连线

运算符之间的连线表示运算符之间传递的方向和数据量。箭头的粗细表示传递的数据量多少。如下图中粗细箭头表示的数据量及其他详细信息如下所示,执行计划从右向左的箭头中的数据量同样可以反应数据查询扫描的行数与最后实际 SELECT 查询的行数差异。

你可能感兴趣的:(程序人生)