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
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
相关文章推荐
- oracle编程入门笔记2015-01-19--表连接
- oracle编程入门笔记2015-01-19--index fast full scan
- oracle编程入门笔记2015-01-07--核心SQL
- oracle编程入门笔记2015-01-12--数据库原理1
- oracle编程入门笔记2015-01-28--model子句原理
- oracle编程入门笔记2015-01-08--查询
- oracle编程入门笔记2015-01-22--解释计划
- oracle编程入门笔记2015-01-30--model子句性能
- oracle编程入门笔记2015-01-25--浅说cube
- oracle编程入门笔记2015-01-10--更新,删除
- oracle编程入门笔记2015-01-14--查询转换
- oracle编程入门笔记2015-02-05--递归查询
- oracle编程入门笔记2015-01-06--基本概念
- oracle编程入门笔记2015-01-12--数据合并
- oracle编程入门笔记2015-01-18--常用oracle查询语句
- oracle编程入门笔记2015-01-18--执行计划中的索引扫描方式说明
- SQL Server 2008编程入门经典笔记:表连接
- oracle编程入门笔记2015-01-27--分析函数性能
- oracle编程入门笔记2015-01-23--执行计划
- oracle编程入门笔记2015-01-17--一个例子告诉你共享池和数据缓存对效率的影响