两表连接二:两表哈希连接

简介: 一、前言: 数据库版本:11.2.0.3 表A1     NUM_ROWS    107,6016(百万级别),没有索引脚本:create table john.

一、前言:

数据库版本:11.2.0.3

表A1     NUM_ROWS    107,6016(百万级别),没有索引脚本:create table john.A1 as select * from all_objects;(然后运行以下脚本几次,产生大量的数据   insert into john.a1 select * from john.a1)表B1    NUM_ROWS  100CREATE TABLE B1(ID  NUMBER);创建表

两表哈希连接是在实际的工作中比较经常遇到的两个表的连接方式,本文档通过实验测试影响两表哈希连接的因素;

 

二、原理介绍

哈希连接处理的两个数据集分别称为构造输入和探测输入。构造输入为左节点,探测输入为右节点。构造输入的每行记录都会被用来在内存中(或临时表空间,如果没有足够内存可用的话)构造哈希表。当哈希表已经包含构造输入的所有数据时,就开始处理探测输入了。探测输入的每行记录都会被拿来对哈希表拿来对进行探测以找出符合连接条件的记录;

 

特征:

每个子节点只会执行一次;

哈希表仅由左节点来构造,因此,一般采用最小的那个节点来构造;

只有在左节点完全处理完毕后,才会返回第一条记录;

不支持交叉连接、条件连接和分区外连接;

 

 

三、测试环境说明:

 

插入数据

 begin

   for i in 1..100 loop                                                       

   insert into B1 values(i);

  if mod(i,100)=0 then

   commit;

   end if;

   end loop;

   end;

   /

 

四、测试方法

本文的测试方法,跟嵌套循环连接的方法一样,通过hint的方法来改变执行计划,并进行比较;

 

测试场景一:直接对量表进行哈希,并比较构造输入为大表和小表时的执行效率;

B1做探测表

select /*+ leading(B1) use_hash(A1,B1) */ * 

from a1,b1

where a1.object_id=b1.id;

 

A1做探测表

select /*+ leading(A1) use_hash(A1,B1) */ *

from a1,b1

where a1.object_id=b1.id;

 

解读:小表作为探测表的执行效率明显比大表作为探测表的执行效率高很多。

在语句2中的执行计划可以看出没有足够的内存存放A1表,导致哈希的时候数据已经存放到了临时表空间了(磁盘的速度跟内存的速度差距不是一点两点的)

 

测试场景二:在连接条件A1的OBJECT_ID增加索引,进行检查执行计划,是否走索引;

select /*+ leading(A1) use_hash(A1,B1) */ *

from a1,b1

where a1.object_id=b1.id;

解读:哈希连接时并不会利用连接条件上面的索引;(嵌套连接会利用)

 

测试三:增加限制条件,并在限制条件上面增加索引;

A1为哈希表:

select /*+ leading(A1) use_hash(A1,B1) */ *

from a1,b1

where a1.object_id=b1.id

AND A1.OBJECT_ID=100;

 

 

B1为哈希表:

select /*+ leading(B1) use_hash(A1,B1) */ *

from a1,b1

where a1.object_id=b1.id

AND A1.OBJECT_ID=100;

 

解读:当限制条件的选择性很强的时候,而这个限制是对大表进行限制的时候,这个时候大表作为哈希表,整体的性能也不会差;

 

................................................................................... 本文作者:JOHN   ORACLE技术博客:ORACLE 猎人笔记

数据库技术群:367875324 (请备注ORACLE管理 )  

...................................................................................

相关文章
|
12月前
|
容器
ThreeJs同一个场景多个相机的显示
这篇文章讲解了如何在Three.js中实现多相机功能,通过创建和布置多个相机及渲染器,从而能够在同一场景中从不同角度观察3D模型。
282 1
|
11月前
|
Anolis 异构计算
|
12月前
|
人工智能 Oracle Java
解决 Java 打印日志吞异常堆栈的问题
前几天有同学找我查一个空指针问题,Java 打印日志时,异常堆栈信息被吞了,导致定位不到出问题的地方。
218 2
|
12月前
|
人工智能 程序员 Python
用通义灵码创建脚本
用通义灵码创建脚本
|
存储 负载均衡 数据管理
分区和分片
分区和分片
470 5
|
消息中间件 缓存 算法
开源7天Github斩获4.5万Stars!阿里2023版高并发设计实录鲨疯了
如何获得高并发经验? 这是我今天逛知乎的时候系统邀请我回答的一个问题,由此也引发了我的一些思考:为什么人人都想要获得高并发经验;想拥有高并发系统设计技能?
|
jenkins Java 程序员
实战:向GitHub提交代码时触发Jenkins自动构建
当我们提交代码到GitHub后,可以在Jenkins上执行构建,但是每次都要动手去执行略显麻烦,今天我们就来实战Jenkins的自动构建功能,每次提交代码到GitHub后,Jenkins会进行自动构建
986 0
实战:向GitHub提交代码时触发Jenkins自动构建
|
Java 索引
多线程并发之CyclicBarrier(栅栏)使用详解
多线程并发之CyclicBarrier(栅栏)使用详解
378 2
|
算法 测试技术
LeetCode的使用方法
LeetCode 是一个上提供一系列的算法题,并且具备多种编程语言优秀在线编辑体验。在这样的基础之上,LeetCode 对于各类题目的描述简洁易懂,题库更新极快,最重要的是它的含金量受到大众的认可,拥有庞大的用户群体,对于每一道算法题基本能够寻找到较好的解题思路。特别说明的是,该平台更为着重对于算法思路的训练,采取的并非 ACM 模式的全包全揽,而是提供一个需要实现的函数,测试用例的定义和主方法的调用等等将由系统提供。 需要训练 ACM 模式的,可以尝试牛客网的刷题模式。 LeeCode 刷题思路 作为一个
443 0
|
存储 缓存 NoSQL
Redis 如何实现库存扣减操作?如何防止商品被超卖?
基于数据库单库存 基于数据库多库存 基于redis 基于redis实现扣减库存的具体实现 初始化库存回调函数(IStockCallback) 扣减库存服务(StockService)。
1070 0
Redis 如何实现库存扣减操作?如何防止商品被超卖?