SQL Server 索引基础知识(10)----Joins 时的三种算法简介
2008-01-23 16:05
666 查看
我们书写查询语句的时候,Join 参数之前可以是下面三个 { LOOP | MERGE | HASH } JOIN 。 如果不使用,则系统自己分析那种方式快,使用那种方式。
这其实是SQL Server 联结时候使用的三种算法。尽管每种算法都并不是很复杂,但考虑到性能优化,在产品级的优化器实现时往往使用的是改进过的变种算法。譬如SQL Server 支持block nested loops、index nexted loops、sort-merge、hash join以及hash team。我们在这里只对上述三种基本算法的原型做一个简单的介绍。
知识点:
Tables join总是两个两个进行的。所以下面的算法都是两个表的联结。
Hash Join (哈希联结) 下图是 SQL Server 标示这种联结的图标,从图标我们就可以看到这个查询的逻辑。
逻辑步骤,如下图: 以数据少的数据表的 Join 字段建立 Hash 值。 对应的数据表计算 Join 字段的 Hash ,再与前一个数据表做比对。
特点: 处理大量、未排序、无索引的数据 一般来说,查询优化器会首先考虑Nested Loop和Sort-Merge,但如果两个集合量都不小且没有合适的索引时,才会考虑使用Hash Join。 Hash Join也用于许多集合比较操作,inner join、left/right/full outer join、intersect、difference等等,当然了,需要保证都是等值联结。 Hash Join一个较大限制是它只能应用于等值联结(equality join),这主要是由于哈希函数及其桶的确定性及无序性所导致的。
Nested Loop Join (嵌套循环联结) 下图是 SQL Server 标示这种联结的图标,从图标我们就可以看到这个查询的逻辑。
逻辑步骤,如下图: 从外层的数据表取出一笔记录 使用这个记录扫描内层的数据表 再回到外层的数据表,重复上述的步骤。
特点: 适用于一个集合大而另一个集合小的情况(将小集合做为外循环),I/O性能不错。 当外循环输入相当小而内循环非常大且有索引建立在JOIN字段上时,I/O性能相当不错。 当两个集合中只有一个在JOIN字段上建立索引时,一定要将该集合作为内循环。 对于一对一的匹配关系(两个具有唯一约束字段的联结),可以在找到匹配元组后跳过该次内循环的剩余部分(类似于编程语言循环语句中的continue)。 可以不是等值联结
Merge Join (合并联结) 下图是 SQL Server 标示这种联结的图标,从图标我们就可以看到这个查询的逻辑。
逻辑步骤。如下图: 使用两个数据表用来 Join 的字段既有的索引 两边的数据表以光标由小到大比较,一边移动到比另一个数据表大时,换移另一个数据表。
特点: 可以不是等值联结 MERGE JOIN 必须等待两个单独的SORT JOIN完成(如果使用索引作为数据源,可以跳过SORT JOIN这个步骤), 如果两个表的规模相差很大, 会很影响查询的性能。 当查询的两个表都很大或者都很小的时候, 则应该只用MERGE JOIN,如果两个表都很小,则表扫描和分类将进行的很快;
分别使用这三种 Join 的例子:
参考资料:
浅谈查询优化器中的JOIN算法
http://blog.csdn.net/hdy007/archive/2007/02/28/1516467.aspx
Example of merge ,hash and nested join
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=498748&SiteId=1
Inside SQL Server Joins
http://blog.csdn.net/happydreamer/archive/2007/05/16/1611523.aspx
这其实是SQL Server 联结时候使用的三种算法。尽管每种算法都并不是很复杂,但考虑到性能优化,在产品级的优化器实现时往往使用的是改进过的变种算法。譬如SQL Server 支持block nested loops、index nexted loops、sort-merge、hash join以及hash team。我们在这里只对上述三种基本算法的原型做一个简单的介绍。
知识点:
Tables join总是两个两个进行的。所以下面的算法都是两个表的联结。
Hash Join (哈希联结) 下图是 SQL Server 标示这种联结的图标,从图标我们就可以看到这个查询的逻辑。
逻辑步骤,如下图: 以数据少的数据表的 Join 字段建立 Hash 值。 对应的数据表计算 Join 字段的 Hash ,再与前一个数据表做比对。
特点: 处理大量、未排序、无索引的数据 一般来说,查询优化器会首先考虑Nested Loop和Sort-Merge,但如果两个集合量都不小且没有合适的索引时,才会考虑使用Hash Join。 Hash Join也用于许多集合比较操作,inner join、left/right/full outer join、intersect、difference等等,当然了,需要保证都是等值联结。 Hash Join一个较大限制是它只能应用于等值联结(equality join),这主要是由于哈希函数及其桶的确定性及无序性所导致的。
Nested Loop Join (嵌套循环联结) 下图是 SQL Server 标示这种联结的图标,从图标我们就可以看到这个查询的逻辑。
逻辑步骤,如下图: 从外层的数据表取出一笔记录 使用这个记录扫描内层的数据表 再回到外层的数据表,重复上述的步骤。
特点: 适用于一个集合大而另一个集合小的情况(将小集合做为外循环),I/O性能不错。 当外循环输入相当小而内循环非常大且有索引建立在JOIN字段上时,I/O性能相当不错。 当两个集合中只有一个在JOIN字段上建立索引时,一定要将该集合作为内循环。 对于一对一的匹配关系(两个具有唯一约束字段的联结),可以在找到匹配元组后跳过该次内循环的剩余部分(类似于编程语言循环语句中的continue)。 可以不是等值联结
Merge Join (合并联结) 下图是 SQL Server 标示这种联结的图标,从图标我们就可以看到这个查询的逻辑。
逻辑步骤。如下图: 使用两个数据表用来 Join 的字段既有的索引 两边的数据表以光标由小到大比较,一边移动到比另一个数据表大时,换移另一个数据表。
特点: 可以不是等值联结 MERGE JOIN 必须等待两个单独的SORT JOIN完成(如果使用索引作为数据源,可以跳过SORT JOIN这个步骤), 如果两个表的规模相差很大, 会很影响查询的性能。 当查询的两个表都很大或者都很小的时候, 则应该只用MERGE JOIN,如果两个表都很小,则表扫描和分类将进行的很快;
分别使用这三种 Join 的例子:
create table t1 ( i int not null ) create table t2 ( i int not null ) go
set showplan_text on go -- Hash Match(Inner Join, HASH:([ghj_Demo].[dbo].[t2].[i])=([ghj_Demo].[dbo].[t1].[i])) select * from t1 join t2 on t1.i = t2.i go set showplan_text off go
alter table t1 add primary key ( i ) alter table t2 add primary key ( i ) go set showplan_text on go -- |--Nested Loops(Inner Join, OUTER REFERENCES:([ghj_Demo].[dbo].[t1].[i])) select * from t1 join t2 on t1.i = t2.i go set showplan_text off go
set showplan_text on go -- Merge Join(Inner Join, MERGE:([ghj_Demo].[dbo].[t1].[i])=([ghj_Demo].[dbo].[t2].[i]), -- RESIDUAL:([ghj_Demo].[dbo].[t2].[i]=[ghj_Demo].[dbo].[t1].[i])) select * from t1 join t2 on t1.i = t2.i option(merge join) go set showplan_text off go drop table t1, t2
参考资料:
浅谈查询优化器中的JOIN算法
http://blog.csdn.net/hdy007/archive/2007/02/28/1516467.aspx
Example of merge ,hash and nested join
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=498748&SiteId=1
Inside SQL Server Joins
http://blog.csdn.net/happydreamer/archive/2007/05/16/1611523.aspx
相关文章推荐
- SQL Server 索引基础知识(10)----Join 时的三种算法简介(转自蝈蝈俊.net)
- SQL Server 索引基础知识(10)----Join 时的三种算法简介
- SQL Server 索引基础知识(10)----Join 时的三种算法简介
- SQL Server 索引基础知识(10)----Join 时的三种算法简介
- SQL Server 索引基础知识(6)----索引的代价,使用场景(转自蝈蝈俊.net)
- SQL Server 索引基础知识(4)----主键与聚集索引
- SQL Server 索引基础知识(6)----索引的代价,使用场景
- SQL Server 索引基础知识(7)----Indexing for AND
- SQL Server 索引基础知识(8)--- 数据基本格式补充
- [转]SQL Server 索引基础知识(1)--- 记录数据的基本格式
- SQL Server 索引基础知识(2)----聚集索引,非聚集索引
- 基础知识——算法复杂度 时间复杂度,空间复杂度简介
- SQL Server 索引基础知识(4)----主键与聚集索引
- SQL Server 索引基础知识(3)
- SQL Server 索引基础知识(1)--- 记录数据的基本格式 (转)
- SQL Server 索引基础知识(3)----测试中一些常看的指标和清除缓存的方法
- SQL Server 索引基础知识(3)----测试中一些常看的指标和清除缓存的方法
- SQL Server 索引基础知识(3)----测试中一些常看的指标和清除缓存的方法
- SQL Server 索引基础知识(2)----聚集索引,非聚集索引
- [转]SQL Server 索引基础知识(2)----聚集索引,非聚集索引