查询优化难点:Join顺序选择 避免误区
作者:网络转载 发布时间:[ 2012/12/10 10:00:17 ] 推荐标签:
可以说Join的顺序是查询优化过程中复杂的问题(当然,这里说的复杂,是对于查询优化器而言,我们很多时候没有看到,也没用怎么在意这个复杂性),因为它涉及到了为每个可选的Join的顺序计算成本。可以这样说:Join的顺序与个数直接与产生候选的执行计划的数量挂钩,从而极大的影响查询优化器的优化过程。
提到Join,我们都很熟悉了:是把来自两个表的基于一些公共的信息进行联合的操作。Join的操作每次都只能在两个表之间进行,因此,如果一个查询要Join的表有N个,那么,需要进行(N-1)次的Join操作,即:先第1个表和第2个表Join,然后Join的结果在和第3个表进行Join,以此类推。
关于Join,查询优化器会根据以下两点做出重要的决定:
1、Join顺序的选择
2、Join算法的选择
在这部分,我们重要谈谈Join的顺序的问题,相信看完之后,一定会让大家对Join有一个全新的认识,至于Join算法,因为这涉及到了执行引擎的部分,我们会在后面的文章中讲述。
之前提过,表的Join的顺序决定了一个查询的性能与成本。对已一个查询而言,可以产生很多的候选执行计划,虽然这些执行计划返回的结果一样,但是不同的Join产生的执行计划的成本确实相差很大的。
因为Join操作有着交换律和结合律的特性,所以,即使一个再简单的查询,也会因为Join的顺序不同而产生很多不同的执行计划,而执行计划的数量也会随着Join表的个数的增加而呈指数倍的增加。而查询优化器的任务是在这些众多的执行计划中选择一个比较优的Join顺序的执行计划。
为了便于理解,我们先来看看几个概念,然后深入的讲述一些例子。
首先看看“交换律”。这一个数学概念,因为SQL Server是关系型数据,其理论基础是关系集合论,而现在的数学都是建立在集合的基础上的,因此SQL Server在设计的时候,也引入了很多的数学的理论。Join操作的体现了交换律:A Join B等于B Join A。
交换律也定义了哪一个表被先访问,例如在一个Nest Loops Join的操作中,首先被访问的表被称之为“外部表”,而第二个表称之为“内部表”。在Hash Join中,首先被访问的表称之为“内部构建表”,第二个表为“探针输入”。定义哪一个表为“外部表”或者为“内部构建表”、“探针输入”对性能的影响都是巨大的。
Join操作的另外一个特性是:结合律,即:(A Join B) Join C等于A Join (B join C),这个概念也不难理解。下面,我们通过一个实例来看看。
我们AdventureWorks示例数据库为例子,我们为下面的这个查询产生实际的执行计划:
我们来看看执行计划,如下:
可以看出:
1、我们在代码中Join的顺序是:(Contact Join Individual)Join Customer,但是在执行计划中的Join顺序却是:(Sales.Customer JOIN Sales.Individual) JOIN Person.Contact。
从这里可以知道:我们在代码中的Join顺序,不见得是后执行计划的顺序,也证明了网络上面流行的一些偏方是错误的:通过改变Join的顺序来提升性能。因为查询优化器相当的智能,对于Join的顺序,它有着自己的决定和考虑。
2、查询优化器会根据很多的信息来决定到底逻辑的Join操作后又哪一种物理Join操作来执行。在例子的代码中,我们的Join都是逻辑的Inner Join,但是后查询优化器会选择合适的物理Join操作,例如对于(Sales.Customer JOIN Sales.Individual),选择的是Merge Join,因为这个两个表是基于聚集索引进行连接,并且数据都是按照聚集索引来排序的(更多的讲述,我们后面文章会涉及)。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11