关系数据库技术的精髓就是经过关系表进行规范化的数据存储,并经过各类表链接技术和各类类型的索引技术来进行信息的检索和处理。sql
表的三种关联方式:数据库
nested loop:从A表抽一条记录,遍历B表查找匹配记录,而后从a表抽下一条,遍历B表........就是一个二重循环
hash join:将A表按链接键计算出一个hash表,而后从B表一条条抽取记录,计算hash值,根据hash到A表的hash来匹配符合条件的记录
sort merge join:将A,B表都排好序,而后作merge,符合条件的选出
对于三种链接,咱们均可以使用hint来强制让优化器走:use_hash,use_nl,use_merge.缓存
Nested Loop Join服务器
1.执行原理oop
例如:
select t1.*,t2.* from t1,t2 where t1.col1=t2.col2;
访问机制以下:
for i in (select * from t1) loop ----t1为驱动表
for j in (select * from t2 where col2=i.col1) loop
display results;
end loop;
end loop;
相似一个嵌套循环
嵌套循环执行时,先是外层循环进入内层循环,并在内层循环终止以后
接着执行外层循环再由外层循环进入内层循环中,当外层循环所有终止时,程序结束
2.步骤以下优化
a.肯定驱动表
b.把inner 表分配给驱动表
c.针对驱动表的每一行,访问被驱动表的全部行
3.执行计划大体以下spa
NESTED LOOPS
outer_loop --驱动表
inner_loop
优化器模式为FIRST_ROWS时,咱们常常会发现有大量的NESTED LOOP
这时,在返回数据给用户时,咱们没有必要缓存任何数据,这是nested loop的一大亮点
4.使用场景.net
通常用在链接的表中有索引,而且索引选择性较好(也就是Selectivity接近1)的时候 也就是驱动表的记录集比较小(<10000)并且inner表须要有有效的访问方法(Index) 须要注意的是:JOIN的顺序很重要,驱动表的记录集必定要小,返回结果集的响应时间是最快的
5.和索引的关系设计
嵌套循环和索引就像一对孪生兄弟,通常须要共同考量与设计,这从优化器的执行机制能够看出.
好比,存在2张表,一个10条记录,一个1000万条记录
以小表为驱动表,则代价为:10*(经过索引在大表查询一条记录的代价)
若是1000万的大表没有索引的时候,那么COST的代价可想而知
所以,在多表链接时,注意被驱动表的链接字段是否须要建立索引
或者链接字段与该表的其余约束条件字段上是否须要建立复合索引
Sort Merge Joincode
1.执行原理
select t1.*,t2.* from t1,t2 where t1.id=t2.id;
访问机制以下:
访问t1,并order by t1_1.id,这里的id表明链接字段
访问t2,并order by t2_1.id
join t1_1.id = t2_1.id,依次交替 比对 归并,但无所谓驱动
2.使用场景
虽然说,hash join就是用来替代sj的,但若是你的服务器的CPU资源和MEM资源都很紧张的时候,建议用SORT MERGE JOIN
由于hash join比sort merge join须要的资源更多。特别是cpu
10g sql tuning 文档上写道:
On the other hand, sort-merge joins can perform better than hash joins if both of the following conditions are met:
The row sources are already sorted.
A sort operation does not have to be done.
因此,sj大概就用在没有索引,而且数据已经排序的状况
参考blog:http://blog.csdn.net/dba_waterbin/article/details/8547451