有两间房间,分别住着男孩和女孩。准备安排跳舞。
方法1:选出男孩,比如小明去女孩房间寻找高度匹配的女孩,然后接着选小军去女孩房选择匹配的女孩。
方法2:男生排队,从高到矮。同时女生房间也排队,从高到矮。然后高对高矮对矮进行男女匹配,一起跳舞。
方法3:女孩按班级在房间里面排成一列,从高到矮,不同班级排到不同的队伍。这时再让男孩根据他们所属的班级到各个队伍去找跟自己匹配的女孩。
方法1就是 Nested Loops Join连接
方法2就是 Merge Sort Join
方法3是Hash Join连接
现实中绝大部分的查询都是NL连接,其次是 Hash join,最是 Merge Sort Join。
在电信、金融等领域的数据库相关应用中,表连接总体的比例情况大致为:Nested Loops Join占了70%左右,而Hash Join占了20%,剩下大致10%是Merge Sort Join。
三大表连接方式的特性
连接类型 | 应用场景 | 表访问次数 | 表驱动顺序与性能 | 是否排序 | 各连接的使用限制 |
Nested Loops Join | 偏局部扫描的OLTP应用 | 驱动表被访问0或者1次,被驱动表被访问0次或者N次,N由驱动表返回的结果集的条数来定 | 小结果集先驱动,性能更好 | 无排序 | 无限制 |
Hash Join | 偏全扫描的OLAP应用 | 驱动表被访问0或者1次,被驱动表也是被访问0次或者1次 | 小结果集先驱动,性能更好 | 无排序,但耗内存(用于建立HASH表) | 不支持连接条件是“>、 < 、<> 、like”的连接方式,简单地说,就是只支持等值连接 |
Merge Sort Join | 偏全扫描的OLAP应用 | 驱动表被访问0或者1次,被驱动表也是被访问0次或者1次 | 驱动顺序和性能无关 | 有排序 | 不支持连接条件是“<> 、like”连接方式,支持“>、 < ” |
连接优化要点
连接类型 | 优化要点 |
Nested Loops Join | 1.驱动表的限制条件要考虑建立索引 2.被驱动表连接条件要考虑建立索引 3.确保小结果集先驱动,大的被驱动 |
Hash Join | 1.两表限制条件有索引 2.要小结果集先驱动,大的被驱动 3.尽量保证PGA能容纳Hash运算 |
Merge Sort Join | 1.两表限制条件有索引 2.连接条件索引消除排序(不完美,可惜的是,ORACLE算法的限制,只能避免一次排序) 3.避免取多余列致排序的尺寸太大(这是由于只取部分字段时,参与排序的尺寸会小很多) 4.PGA能完成排序,避免磁盘排序 |
排序合并连接和哈希连接有些类似,都是基于吞吐量的操作,返回大量的甚至所有的数据时显然比嵌套循环连接要高效,但是两者还是有区别的,哈希连接不算排序,由PGA中的HASH AREA SIZE参数来控制,而排序合并连接则是由PGA中的SORT_AREA_SIZE参数控制的。HASH连接使用的是HASH算法,比排序合并连接更高效一些,但是HASH连接使用更受限制。
索引对于嵌套循环连接来说非常重要,既要考虑驱动表的限制条件上的索引,又要考虑被驱动表上的连接条件上的索引;对于哈希连接和排序合并连接来说,索引的连接条件起不到快速检索的作用,但是限制条件列如果有适合的索引可以快速检索到少量记录,还是可以提升性能的。而索引对于哈希连接来说,仅仅是考虑限制条件上的索引是否能用上索引,连接条件上的索引是不能发挥作用的;排序合并连接和哈希连接又有差别,排序合并连接上的连接条件虽然没有检索的作用,却有消除排序的作用,这点请大家务必注意。