哈希连接(hash join) 原理
哈希连接(hashjoin)
访问次数:驱动表和被驱动表都只会访问0次或1次。
驱动表是否有顺序:有。
是否要排序:否。
应用场景: 1. 一个大表,一个小表的关联;
2. 表上没有索引;
3. 返回结果集比较大。
原理我们说的简单一点,先把驱动表的关联字段hash到PGA中(当然rowid也在PGA中),然后扫描被驱动表,取第一条数据,将关联的字段hash 一下探测PGA中的小表,如果匹配则关联,再取第二条........。
下面我们来做个试验:
SQL> create table test1 as select * from dba_objects where rownum <=100;
SQL> create table test2 as select * from dba_objects where rownum <=1000;
SQL> exec dbms_stats.gather_table_stats(user,'test1');
SQL> exec dbms_stats.gather_table_stats(user,'test2');
SQL> alter session set statistics_level=all;
SQL> select /*+leading(t1) use_hash(t2)*/count(*)
from test1 t1, test2 t2
where t1.object_id = t2.object_id;
COUNT(*)
----------
100
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 3f2mts0kt82u2, child number 0
-------------------------------------
select /*+leading(t1) use_hash(t2)*/count(*) from test1 t1, test2 t2 where t1.object_id = t2.object_id
Plan hash value: 2544416891
----解释一下:
Starts为该sql执行的次数。
E-Rows为执行计划预计的行数。
A-Rows为实际返回的行数。A-Rows跟E-Rows做比较,就可以确定哪一步执行计划出了问题。
A-Time为每一步实际执行的时间(HH:MM:SS.FF),根据这一行可以知道该sql耗时在了哪个地方。
Buffers为每一步实际执行的逻辑读或一致性读。
Reads为物理读。
OMem、1Mem为执行所需的内存评估值,0Mem为最优执行模式所需内存的评估值,1Mem为one-pass模式所需内存的评估值。
0/1/M 为最优/one-pass/multipass执行的次数。
Used-Mem耗的内存
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 19 | | | |
|* 2 | HASH JOIN | | 1 | 100 | 100 |00:00:00.01 | 19 | 1066K| 1066K| 1162K (0)|
| 3 | TABLE ACCESS FULL| TEST1 | | 1000 | 1000 |00:00:00.01 | 15 | | | |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
SQL> select /*+leading(t1) use_hash (t2)*/count(*)
from test1 t1, test2 t2
where t1.object_id = t2.object_id
and t1.object_id = 99999;
COUNT(*)
----------
0
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID f9zwsrs05kg0n, child number 0
-------------------------------------
select /*+leading(t1) use_hash (t2)*/count(*) from test1 t1, test2 t2 where t1.object_id =
t2.object_id and t1.object_id = 99999
Plan hash value: 2544416891
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 4 | | | |
|* 2 | HASH JOIN | | 1 | 1 | 0 |00:00:00.01 | 4 | 921K| 921K| 176K (0)|
|* 3 | TABLE ACCESS FULL| TEST1 | | 1 | 0 |00:00:00.01 | 4 | | | |
|* 4 | TABLE ACCESS FULL| TEST2 | | 1 | 0 |00:00:00.01 | 0 | | | |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
3 - filter("T1"."OBJECT_ID"=99999)
4 - filter("T2"."OBJECT_ID"=99999)
SQL> select /*+leading(t1) use_hash (t2)*/count(*)
2 from test1 t1, test2 t2
3 where t1.object_id = t2.object_id
4 and 1=2;
COUNT(*)
----------
0
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID bnrfbt4ybxnnp, child number 0
-------------------------------------
select /*+leading(t1) use_hash (t2)*/count(*) from test1 t1, test2 t2 where t1.object_id =
t2.object_id and 1=2
Plan hash value: 1013001923
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | OMem | 1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | | | |
|* 2 | FILTER | | 1 | | 0 |00:00:00.01 | | | |
|* 3 | HASH JOIN | | 0 | 100 | 0 |00:00:00.01 | 921K| 921K| |
| 4 | TABLE ACCESS FULL| TEST1 | | 100 | 0 |00:00:00.01 | | | |
| 5 | TABLE ACCESS FULL| TEST2 | | 1000 | 0 |00:00:00.01 | | | |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(NULL IS NOT NULL)
3 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
哈希连接(hash join) 原理的更多相关文章
- oracle 表连接 - hash join 哈希连接
一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...
- oracle多表连接方式Hash Join Nested Loop Join Merge Join
在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式: 嵌套循环(Nested Loops (NL) ...
- Oracle 三种连接方式 NESTED LOOP HASH JOIN SORT MERGE JOIN
NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择.在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大( ...
- HASH JOIN算法
哈希连接(HASH JOIN) 前文提到,嵌套循环只适合输出少量结果集.如果要返回大量结果集(比如返回100W数据),根据嵌套循环算法,被驱动表会扫描100W次,显然这是不对的.看到这里你应该明白为 ...
- Oracle 哈希连接原理
<基于Oracle的sql优化>里关于哈希连接的原理介绍如下: 哈希连接(HASH JOIN)是一种两个表在做表连接时主要依靠哈希运算来得到连接结果集的表连接方法. 在Oracle 7.3 ...
- 数据库 Hash Join的定义,原理,算法,成本,模式和位图
Hash Join只能用于相等连接,且只能在CBO优化器模式下.相对于nested loop join,hash join更适合处理大型结果集 Hash Join的执行计划第1个是hash ...
- 多表连接的三种方式详解 hash join、merge join、 nested loop
在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...
- 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)
简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...
- Merge join、Hash join、Nested loop join对比分析
简介 我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge Join,Hash Join ...
随机推荐
- [故障引起的故事]URL中带加号的处理
问题起因: 客户订购了一关键字为"e+h 变送器" , 在首页推荐广告中,会根据用户在search 搜索过的关键字进行一个匹配投放.技术实现是UED 通过JS 获取coo ...
- Nexus 使用配置
Nexus使用的一些基本设置 1.更改中央仓库地址为私服地址 既然我们配置了私服,那么相应的,我们的项目就应该使用Nexus的地址(Public Repository)来下载jar包 1.1.基于PO ...
- Java开发微信公众号
1.https://natapp.cn/ 2.选择和自己电脑相对应的系统下载 (以windows为例)下载并解压在磁盘中(记住解压文件的位置 例如:E:\dailysoftware\ngrok_wi ...
- Python sum() 函数
Python sum() 函数 Python 内置函数 描述 sum() 方法对系列进行求和计算. 语法 以下是 sum() 方法的语法: sum(iterable[, start]) 参数 ite ...
- chest
chest - 必应词典 美[tʃest]英[tʃest] n.胸部:胸膛:有…胸的:胸部…的 网络胸围:箱子:胸腔 变形复数:chests:
- Redis网络协议
Redis网络协议较为简单,易于阅读. 命令或数据已\r\n结尾,但除了状态回复,其他数据都是二进制安全的(包含长度) 头部如下: + 正确的状态信息,具体信息是当前行+后面的字符. - 一条错误信 ...
- 转)Ubuntu安装mysql5.7
主要参考http://blog.csdn.net/q894523017/article/details/50705392 包去官网下载,解压,安装步骤如下: 上文中有错误,正确如下: sudo dpk ...
- 【校招面试 之 C/C++】第12题 C++ 重载、重写和重定义
1.成员函数重载特征: a.相同的范围(在同一个类中): b.函数名字相同: c.参数不同(参数个数不同或者参数类型不同,但是返回值不同不能使重载): d.virtual关键字可有可无. 2.重写 ...
- Ubuntu-18.04Python2与Python3自由切换
一.配置ssh链接 安装openssh-server devops@devops-virtual-machine:~$ sudo apt-get install openssh-server 二.安装 ...
- Zabbix监控PostgreSQL
目录 Zabbix监控PostgreSQL 1. 安装libzbxpgsql 2. 配置zabbix配置文件zabbix_agentd.conf 3. 创建监控用户 4. 导入监控模板 5. 主机链接 ...