每天在讨论Microsoft SQL Server的各种讨论板中,相同类型的问题一再出现:为什么这个查询运行缓慢? 我的索引是否被使用? 为什么我的索引不被使用? 为什么此查询比此查询运行得更快? 正确的答案在每种情况下可能不同,但为了得到答案,你必须在每种情况下问同样的回答问题:你看过执行计划吗?
什么是执行计划
执行计划,简单地说,是查询优化器尝试计算最有效的方式来实现由您提交的T-SQL查询请求的表示结果。
执行计划可以告诉您如何查询如何执行的,或查询将要以什么方式去执行。因此,它们是DBA对性能较差的查询进行故障排除的主要方法。而不是简单的去猜测为什么给定的查询执行数千次扫描,您可以使用执行计划来确定导致问题的SQL代码的确切部分。例如,一个查询可能需要扫描整个表格的数据,但是当使用适当的索引时,它可以简单地只扫描所需的行。这些和更多的信息都显示在执行计划中。
本章的目的是使您能够以图形,文本或XML 的格式捕获实际和估计的执行计划,并学习如何解它们。为此,我们将介绍以下主题:
查询优化器的简要背景知识 - 执行计划是查询优化器计算的结果,因此需要至少了解一下查询优化器是什么以及工作原理是什么
实际和估计执行计划 - 它们是什么和如何不同
捕获和解释不同的可视执行计划格式 – 将解读一个基本的SELECT查询的图形,文本和XML执行计划
自动执行计划捕获 - 使用SQL Server Profiler工具
SQL Server如何来处理提交的查询请求
查询解析器
当你向SQL Server系统传递一个T-SQL查询时,它的第一个地方就是关系引擎(relational engine)。
当T-SQL语句到达时,它通过一个进程(解析器进程),检查T-SQL是否语法正确和是否是适当的格式。此过程称为查询解析。解析器进程的输出是解析树,或查询树(或序列树)。解析树表示执行请求查询所需的逻辑步骤。
如果请求的T-SQL不是数据操作语言(DML)语句,它将不会被优化。例如SQL Server系统只有一种“正确的方式”来创建表;因此,没有机会改善这种语句的性能。如果请求的T-SQL是DML语句,则将解析树传递给称为Algebrizer的进程。Algebrizer 的主要作用:绑定,也就是说,验证查询中用到的表与列是否存在;加载这些表和列的元数据;识别查询中所有的数据类型;为 algebrizer 树中所需要的隐式数据转换(类型转换)添加必要的信息;对查询中所有的视图,用其定义替换;核实 GROUP BY 以及聚集函数的使用是否得当;并执行一些简单的基于语法的优化。
Algebrizer进程是很重要的,因为查询语句中可能具有别名或同义词,数据库中不存在的名称或引用不在数据库中的对象。
查询优化器并不直接在查询的原始文本上工作,它需要一个更加结构化的输入。Algebrizer 的任务就是产生二进制的 algebrizer tree,这棵树表示了查询的逻辑结构,然后将其传递给查询优化器。 因为我们有编译后的执行计划,所以不需要缓存 Algebrizer 树。
查询优化器
查询优化器本质上是一个模拟数据库关系引擎工作的程序模型。将查询处理树(algebrizer tree)和统计信息(statistics ),传到该模型,他将会挑选出它认为将是执行该查询的最佳方式 - 也就是说,它最终会生成一个执行计划。
换句话说,优化器将确定如何最好地实现您提交的T-SQL查询请求。它决定是否可以通过索引访问数据,使用什么类型的连接等等。优化器做出的决策是基于给定执行计划的执行成本,包括所需的CPU和I / O以及执行速度。因此,这被称为基于成本的计划。
优化器将生成和评估很多种不同的计划(除非已经有一个缓存计划),一般来说,将选择最低成本的计划,即它认为该计划是执行查询最快,并且使用最少的资源(CPU和I / O)。执行速度的计算是最重要的计算,优化器将尝试使用更多的CPU进程来看是否更快地返回结果。有时如果优化器认为评估许多计划比运行效率较低的计划需要更多的时间,则优化器将选择效率较低的计划。
如果您提交一个非常简单的查询 - 例如,仅查询没有索引的单个表中特定字段值,没有聚合或计算。 对于这种类型的查询,优化器将简单地应用一个平常的查询计划而不是花费时间计算绝对的最优计划。如果查询不是平常的简单查询,优化器将依赖于由SQL Server维护的统计信息来生成基于执行成本的最优计划。
优化器接收查询处理树(algebrizer tree)和统计信息(statistics ),并启发式地确定最佳计划。这意味着它将会生成一系列的计划,然后测试不同类型的连接,连接顺序,尝试不同的索引等等,直到到达它认为将是最快的计划。在这些计算期间,向计划中的每个步骤分配一个数字,表示优化器认为该步骤将花费的时间量的估计。这个数字将会代表该步骤的估计成本。把每个步骤的成本累积就是该执行计划的成本。需要特别注意的是,估计成本只是一个估计。
给定无限的时间和完整的最新的统计信息,优化器将找到执行查询的完美计划。然而,事实上是不可能的。优化器试图在尽量短的时间内计算获得最佳计划,显然受到其可用的统计信息的质量的影响。因此,这些成本估计作为预测是非常有用的,但可能不会精确地反映现实执行状况。
一旦优化器挑选出最优的执行计划方案,这个计划将会创建并将其存储在执行计划高速缓存的存储器空间中 - 除非高速缓存中已经存在相同的计划。当优化器在生成潜在计划时,会将它们与高速缓存中之前生成的计划进行比较。如果找到匹配的,它将使用该计划而不会重新评估是否最优。
查询执行
一旦生成了执行计划,SQL Server 将会根据该计划切换到查询被实际执行的存储引擎(storage engine)中。关系引擎将会返回查询语句要求的格式数据并将结果返回给你(假如是个select语句)