码迷,mamicode.com
首页 > 其他好文 > 详细

详解索引连接类型

时间:2015-07-06 12:02:44      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

原文:详解索引连接类型

  SQL Server有3种连接类型:

  • Hash连接;
  • 合并连接;
  • 嵌套循环连接;

  在许多影响小的行集的简单查询中,嵌套循环连接远远优于hash和合并连接。用于查询的连接类型由优化器动态决定。

  下面我来先来建立两张简单的表。Province(十条数据)=》PersonTenThousand(1万数据),省份和人的关系,一对多,外键相连;

一、Hash连接

  为了理解哈希连接,在这个连接中PersonTenThousand在连接列PId上没有任何索引,先来看看如下查询:

  技术分享

  可以看到,优化器在两个表之间使用了Hash连接。这种情况经常出现于下表(大表)较大,并且下表(大表)的连接列上没有索引。

  Hash连接使用两个连接输入-建立输入和探查输入。建立输入是执行计划中上面的那个输入(小表),探查输入是下面那个输入(大表)。两个输入中较小的一个作为建立输入。

  Hash连接的执行分为两个阶段:建立阶段和探查阶段。在最常用的Hash连接方式-内存中的Hash连接中,整个建立输入被扫描或计算,然后再内存中建立一个Hash表。每个行根据计算的Hash键值(相当于断言中的一组列)被插入到一个Hash表元中。

  这个建立阶段之后是探查阶段。整个探查输入被逐行进行扫描或计算,对于每个探查行,计算一个Hash键值。对应的Hash表元使用来自探查输入的Hash键值进行扫描,匹配被生成。

  查询优化器使用Hash连接高效处理大的、未排序、没有索引的输入。通常:所求数据在其中一方或双方没有排序的条件达成时,会选用哈希匹配。

二、合并连接

  先看下面的查询:

  技术分享

  对于这个查询,优化器使用两个表之间的一个合并连接。合并连接要求两个连接输入在合并列上排序,这将在连接条件中定义。如果两个连接上有索引,那么连接输入由该索引排序。因为每个连接输入都被排序,合并排序从每个输入得到一行比较是否相等,如果它们相等,匹配的行被生成。这个过程重复道所有行都被处理。

三、嵌套循环

  在以上的查询中,下面我们将在PersonTenThousand表的PId(连接列)上建立聚集索引,在运行相同的查询:

  技术分享

  嵌套循环连接使用一个连接输入作为外部输入表,另一个作为内部输入表。外部输入表是执行计划中上面的输入,而内部输入表是下面的输入表。外部循环逐行消费外部输入表。内部循环为每个外部行执行一次,搜索内部输入表的匹配行。

  如果外部输入相当小,内部输入大但是有索引,嵌套循环连接是非常高效的。在许多影响少数行的简单查询中,嵌套循环连接远远优于Hash和合并连接。连接通过牺牲其他方面来提高速度-使用内存来取得小的数据集并且快速地与第二个数据集比较,循环连接熟读很快。合并连接与此相似,使用内存和一小部分tempdb来进行其排序的比较,Hash连接使用内存和tempdb建立hash表。虽然循环连接更快,但是随着数据集变得更大,它比Hash或合并消耗更多的内存,这就是SQL Server在不同数据集的情况下使用不通计划的原因。

连接类型 连接列上的索引 连接表的一般大小 预先排序 连接子句
Hash

内部表:不需要索引

外部表:可选

最佳条件:小的外部表,大的内部表

任意 不需要 Equi-join
合并

内部/外部表:必须有索引

最佳条件:两个表都有聚集或覆盖索引

需要 Equi-join
嵌套循环

内部:必须索引

外部:最好有索引

可选 所有

   要注意排序条件。上面的表格总结的已经非常好了,要不是说最佳条件覆盖索引,我到现在都搞不出合并连接的示例。

 

详解索引连接类型

标签:

原文地址:http://www.cnblogs.com/lonelyxmas/p/4623884.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!