您的位置:首页 > 数据库 > Oracle

oracle编程入门笔记2015-01-19--四种表连接

2015-01-20 14:55 176 查看
1.循环嵌套连接(nested loop)

nested loop 用java描述大概就是一个双层循环

for(遍历驱动表)

{

for(遍历被驱动表)

{根据驱动表的条件}

}

使用嵌套循环的条件是驱动表记录返回的记录较少,这样,使用nested loop总体的循环次数较少。例如



这样是不会使用nested loop。因为没有其他帅选条件,无论哪张表作为驱动表,循环次数都是全表记录。所以只能用hash join 的方式,用空间换时间、

加个条件缩小一下员工表的记录数。



这样员工表由于记录变少,所以可以采用nested loop的方式来关联。

总结:nested loop由于是一次在外层循环取一条记录作为条件去查找被驱动表,所以比较省内存,但是耗时间。

2.排序-合并连接(merge join-sort join)

这种连接方式其实细分是两步,第一步,按照关联字段将表排序

第二部,将排序后的两张表合并。具体使用什么合并算法是在不断优化的。现在阐述一种简单高效的合并算法,cpu轮流扫描两张表,比较最上面的数据行,丢弃在排序队列中比另一张表最上面一行出现的早的数据行,返回匹配的数据行。



总结:merge join-sort join 是把两张表中where筛选的结果都加到内存中然后进行排序合并操作。这样其实消耗了比较多的内存,还有cpu。所以一般比较少的情况下出现这种,一般都是hash join。但是通常谓语有范围的时候,hash join 失效才会选用这种。

3.散列连接(hash-join)

散列连接和排序归并连接差不多,不过没有排序过程。

散列连接分两步,第一步将驱动表安装连接字段使用哈希函数散列到散列桶里。(不要纠结散列桶是什么,其实这东西是别人翻译过来的,可以理解为一张链式表,存了连接字段的哈希值等)。

第二部,扫描被驱动表。一行行使用同样的哈希函数散列关联字段,如果存在于散列桶中,保留,不存在剔除。



总结:散列连接,驱动表需要的数据块会直接放到内存中,被驱动表只需要遍历一次。但是因为是根据哈希值匹配,所以只能用于where中条件为等于。对于其他非等式例如between and会采用排序归并连接。

4.笛卡尔连接

笛卡尔连接就是两张表直接相连,没有任何条件。结果集大小是两表的乘积。



以上就是一个笛卡尔积。注意buffer sort并不是真正的在排序,见https://blogs.oracle.com/toddbao/entry/buffer_sort%E6%98%AFbuffer%E5%8D%B4%E4%B8%8D%E6%98%AFsort,oracle使用缓冲区排序。提笛卡尔积,是因为有些人发现查询结果有重复数据,就加distinct,不仅distinct消耗cpu,根本问题笛卡尔积还消耗内存。所以要注意检查一下。

最后补充一点东西

有时候能看到在以上介绍的连接方式后面有

outer:代表外连接。外连接的驱动表一定是外连接的表,驱动表所有记录都会被返回。

semi:代表只要被驱动表里面存在一条满足条件的记录,就返回驱动表中记录。仅返回一条,一般用于in,exists

anti:代表被驱动表中不存在满足条件的记录,就返回驱动表中的记录。用于not in,not exists
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: