欢迎回到 性能调优培训 。今天标志着第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 A 2 INNER JOIN B ON A.ID = B.ID 3 WHERE A.X = 'SomeValue'
在那个查询里,你告诉数据库:
你通过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里执行计划缓存的更多细节,还有执行计划缓存为什么是重要又危险的概念。请继续关注!