你的位置:首页 > 数据库

[数据库]第9/24周 理解执行计划


欢迎回到性能调优培训。今天标志着第3个月的培训开始了,这个月我们全部学习SQL Server里的执行计划。执行计划在SQL Server里是你需要理解的,最重要的概念,对它做出有效的调整,就可以提高查询性能。因此今天我会大致介绍下SQL Server里的执行计划,还有你如何读懂它们。

为什么会有执行计划

很多人经常问我在SQL Server里为什么需要执行计划。我们已经有了SQL Server的查询,但为什么SQL Server还需要执行计划呢?为什么SQL Server不自己执行查询呢?为了回答那个问题,我们需要进一步讨论下SQL语言。SQL语言(在SQL Server也叫做T-SQL)是一个解释性的语言(declarative language) 。你用一种逻辑的方式介绍从你数据库想要的数据(SELECT查询),或者在你数据里你想要修改的数据(INSERT, UPDATE, DELETE查询)。就看下下面的查询。

1 SELECT A.*, B.* FROM A2 INNER JOIN B ON A.ID = B.ID3 WHERE A.X = 'SomeValue'

在那个查询里,你告诉数据库:

  1. 你想要从表A和表B获取数据
  2. 2个表需要通过ID列进行连接
  3. 表A里的行需要在X列上进行过滤

你通过SQL语句来描述数据库的查询结果是什么样的。用SQL语句你只指出结果,没其他任何信息。你没有告诉SQL Server如何执行这个查询,即获取数据的流程。

你总是和SQL Server以逻辑的方式打交道,描述下你想要获取的数据,或者你想要修改的数据。但是SQL Server本身是需要一个实际执行计划来描述如何获取或修改数据的步骤。这个执行计划就是被称为查询优化器(Query Optimizer)拿来处理你SQL查询的策略

这是我们现实生活的华丽重现:想下你要从一个城市到另一个城市旅游。例如你想从伦敦到巴黎旅游,你就定义了一个逻辑描述。当然,那个逻辑描述可以有多个实现方式:

  • 你可以从伦敦走到巴黎
  • 你可以骑车过去
  • 你可以坐汽车/火车/飞机

选择哪个并不重要,其实这里有很多不同的组合方式。你的旅行方式就会非常多。你肯定会选择成本关联最低的方式:坐飞机直达。在SQL Server里的查询优化器也做着同样的工作:查询优化器会选择满足你查询最省力的执行计划。对于查询优化器的挑战就是:从查找空间(Search Space)里,找到足够好(good enough)的执行计划!查找空间就是在你查询里涉及到的大量表和索引。

如何阅读执行计划

第一次接触到执行计划时,你会碰到很多困难:你不能正确理解和读懂它们。来看下下面的执行计划:

从上图可以看到,每个执行计划包含很多步,在SQL Server里被称为运算符(Operator) 。这些运算符被SQL Server逐个调用。这就是说在执行计划里,运算符的执行流是从右到左的(从上到下)。

这里的SQL Server执行的第一步是:在Address表上的索引查找(非聚集索引)(Index Seek(Non Clustered))运算符。从扫描回来的每条记录进入嵌套循环(Nested Loop)运算符。对于获取的每条记录,SQL Server在Address表进行了键查找(聚集索引)(Key Lookup (Clustered) )运算符(一种书签查找)。如果有匹配的行,这行就会传给SELECT运算符,即把最终结果返回给程序。

从上面的描述,我们可以看到,刚开始阅读执行计划时,从右往左更容易,因为在执行计划里,数据也是这样流的。执行计划实际上也是从右往左执行的。当我们从右到左跟着数据时,我们是在一种逻辑的方式阅读执行计划。

希望这种方式可以更好的帮你理解如何读懂执行计划。如果你想看看在SQL Server里,执行计划支持哪些运算符,我推荐Fabiano Amorim的免费电子书《Complete Showplan Operators (PDF)》。

小结

这期的性能调优培训,我们弄清楚了SQL Server为什么需要执行计划,还有如何读懂执行计划。如你所看到的,我们和SQL Server是以逻辑的方式打交道:我们通过SQL查询描述数据库里我们想要的数据,或者我们想要修改的数据。

查询优化器的工作就是对这些查询生成足够好的执行计划。执行计划最终描述SQL Server实际执行步骤,来满足并执行我们的查询。下周我们会聚焦SQL Server里执行计划缓存的更多细节,还有执行计划缓存为什么是重要又危险的概念。请继续关注!