Oracle nested loops、hash join、sort merge join 详解

表连接方式

  • 理论执行效率:hash join > nested loops > sort merge join
  • CBO 优化器下,表连接方式不是固定的,可通过 hint 关键字进行强制变更。
  • 优化不变原则:IO 消耗最小
表连接方式 工作原理 适用原则
nested loops 嵌套循环 2层嵌套循环 1.驱动表数据量 < 1W
2.被查找表有索引
hash join 散列连接 较小的表在 RAM 创建 hash table,较大的表读取记录,效率最高 1.等值连接
2. 驱动表大时,效果较好;驱动表小时,效果更好
3. 需要设置参数 HASH_AREA_SIZE
sort merge join 排序合并连接 记录排序然后合并 1. 非等值连接或排序
star join 星型连接 多个维度表 和一个大的 数据表,然后嵌套循环连接 1.一般用于 数据仓库
2. 需要启用参数 STAR_TRANSFORMATION_ENABLED

在这里插入图片描述

nested loops 嵌套循环

  • 循环地 从一张表中读取数据(驱动表 outer table),然后访问另一张表(被查找表 inner table,通常有索引)。驱动表中的每一行与 inner 表中的相应字段关联。
FOR o IN 1 .. n LOOP -- 一般 n < 1W
  FOR i IN 1 .. m LOOP
     索引字段 join;
  END LOOP;
END LOOP

-- 内部连接过程
row source1 的 row1 -> probe -> row source2
row source1 的 row2 -> probe -> row source2
row source1 的 row3 -> probe -> row source2
...
row source1 的 rowN -> probe -> row source2

hash join 散列连接

  • 这种连接方式是 Oracle 7.3 引入的,只能用于 CBO 优化器中
  • 也有 nested loops 中所谓的驱动表概念,被 hash table 与 bitmap 的表为驱动表,当被构建的 hash table 与 bitmap 能被容纳在内存中时,这种连接方式的效率极高。
-- 内部连接过程
row source1 的 row1 -> build hash table and bitmap -> probe -> row source2
row source1 的 row2 -> build hash table and bitmap -> probe -> row source2
row source1 的 row3 -> build hash table and bitmap -> probe -> row source2
...
row source1 的 rowN -> build hash table and bitmap -> probe -> row source2

sort merge join 排序合并连接

  • 先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配。
  • 因为 merge join 需要做更多的排序,所以消耗的资源更多。 通常来讲,能够使用 merge join 的地方,hash join 都可以发挥更好的性能,即散列连接的效果都比排序合并连接要好。然而如果行源已经被排过序,在执行排序合并连接时不需要再排序了,这时排序合并连接的性能会优于散列连接

hint 关键字

  • 注意检查语法:select /*+ hint*/ .../* 和 + 之间不能有空格,且必须紧跟 select 之后,否则无效
  • 使用表别名:如果指定了表别名,就不能使用表名称
  • 提示忽略:如果写错了,会被当做注释,不产生作用
表连接常用 hint 关键字 功能描述
/*+ LEADING(t)*/ 将指定的表 t 作为连接次序中的首表
/*+ USE_NL(t1 t2)*/ 强制将 t1,t2 使用嵌套循环
/*+ USE_HASH(t1 t2)*/ 强制将 t1,t2 使用散列连接
/*+ USE_MERGE(t1 t2)*/ 强制将 t1,t2 使用排序合并
/*+ PARALLEL(t N)*/ 并行,表 t,并发数 N
/*+ INDEX(t idx)*/ 索引,表 t,索引名 idx
SELECT /*+ leading(t1) use_hash(t1 t2)*/
 t1.*
  FROM table_a t1, 
       table_b t2
 WHERE t1.a = t2.a;

猜你喜欢

转载自blog.csdn.net/qq_34745941/article/details/96476848