zoukankan
html css js c++ java
Hash Join是Oracle CBO时代经常出现的一种连接方式
Hash Join是Oracle CBO时代经常出现的一种连接方式
,对海量数据处理时经常出现在
执行计划
里。本篇的上篇(
http://space.itpub.net/17203031/viewspace-697442
)
介绍了Hash Join的一些外部特征和操作算法流程,下面我们一起看下一些影响到Hash Join的重要参数和内部指标。
3
、
Hash Join
相关参数
Hash Join
是
CBO
优化器才能生成的执行计划操作,如果是选择了
RBO
就不能生成包括
Hash Join
的执行计划。此外,与
Hash Join
相关的
Oracle
参数还包括下面几个:
ü
Hash_Join_Enable
该参数是控制
CBO
启用
Hash Join
的开关。如果设置为
True
,则表示
CBO
可以使用
Hash Join
连接方式,否则就不可以使用。在目前的版本中,该参数已经演化为一个隐含参数,名称为“
_hash_join_enable
”。
SQL> col name for a20;
SQL> col value for a10;
SQL> col DESCRIB for a30;
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
2
FROM SYS.x$ksppi x, SYS.x$ksppcv y
3
WHERE x.inst_id = USERENV ('Instance')
4
AND y.inst_id = USERENV ('Instance')
5
AND x.indx = y.indx
6
AND x.ksppinm LIKE '%hash_join_enable%';
NAME
VALUE
DESCRIB
-------------------- ---------- ------------------------------
_hash_join_enabled
TRUE
enable/disable hash join
该参数的隐式化,也就说明了
CBO
已经成熟到一定程度,
Oracle
官方不希望我们禁用掉这种
Hash Join
连接方式。当然,我们可以从
system
和
session
两层均可以暂时的禁用掉
hash Join
。
//
此时
_hash_join_enable=true
SQL> explain plan for select * from segs, tabs where segs.segment_name=tabs.table_name;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2106473715
---------------------------------------------------------------------------
| Id
| Operation
| Name | Rows
| Bytes | Cost (%CPU)| Time
|
---------------------------------------------------------------------------
|
0 | SELECT STATEMENT
|
|
990 |
354K|
25
(4)| 00:00:01 |
|*
1 |
HASH JOIN
|
|
990 |
354K|
25
(4)| 00:00:01 |
|
2 |
TABLE ACCESS FULL| TABS |
968 |
229K|
11
(0)| 00:00:01 |
|
3 |
TABLE ACCESS FULL| SEGS |
2267 |
274K|
13
(0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("SEGS"."SEGMENT_NAME"="TABS"."TABLE_NAME")
15 rows selected
//session
层面禁用
hash_join
连接
SQL>
alter session set "_hash_join_enabled"=false;
Session altered
NAME
VALUE
DESCRIB
-------------------- ---------- ------------------------------
_hash_join_enabled
FALSE
enable/disable hash join
//
相同的
SQL
,此时参数环境已经变化;
SQL> explain plan for select * from segs, tabs where segs.segment_name=tabs.table_name;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------
Plan hash value: 3475644097
------------------------------------------------------------------------------------
| Id
| Operation
| Name | Rows
| Bytes |TempSpc| Cost (%CPU)| Time
|
------------------------------------------------------------------------------------
|
0 | SELECT STATEMENT
|
|
990 |
354K|
|
144
(2)| 00:00:02 |
|
1 |
MERGE JOIN
|
|
990 |
354K|
|
144
(2)| 00:00:02 |
|
2 |
SORT JOIN
|
|
968 |
229K|
712K|
65
(2)| 00:00:01 |
|
3 |
TABLE ACCESS FULL| TABS |
968 |
229K|
|
11
(0)| 00:00:01 |
|*
4 |
SORT JOIN
|
|
2267 |
274K|
824K|
79
(2)| 00:00:01 |
|
5 |
TABLE ACCESS FULL| SEGS |
2267 |
274K|
|
13
(0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("SEGS"."SEGMENT_NAME"="TABS"."TABLE_NAME")
filter("SEGS"."SEGMENT_NAME"="TABS"."TABLE_NAME")
已选择
18
行。
可见,当我们
session
级别禁用了
hash Join
连接之后,
CBO
不能进行
Hash Join
路径选择。于是选择了
Merge Join
路径,显然无论是执行时间还是
CPU
成本,
Merge Join
略逊一筹。
ü
Hash_Area_Size
Hash Join
操作是依赖独立的私有空间,我们称之为
Hash_Area
。
Hash Area
在
Join
过程中的作用就是将连接小表尽可能的缓存在
Hash Area
中,供进行
Hash
匹配和
Bucket
内部精确匹配。
Hash Area
是贮存在
PGA
中,属于会话
session
独立的一块空间。如果
Hash Area
较小,不足以存放小表全部数据,就会引起
Temp
表空间的使用,进而影响
Hash Join
性能。
SQL> show parameter hash
NAME
TYPE
VALUE
------------------------------------ ----------- ------------------------------
hash_area_size
integer
131072
因为每一个会话都会开启一个
Hash Area
进行
Hash
操作,所以通常
Hash Area
的大小不会设置很大。与
Hash Area
类似的空间是
Sort Area
,用于进行
SQL
语句中的
Order by
操作,也是一个依赖分配的参数项目。通常,
Hash Area
被分配大小为
Sort Area
的两倍。
SQL> show parameter sort_area
NAME
TYPE
VALUE
------------------------------------ ----------- ------------------------------
sort_area_retained_size
integer
0
sort_area_size
integer
65536
进入
Oracle 9i
之后,特别是
10g
出现,
Oracle
共享内存和独占内存分配策略呈现自动化和自适应化的趋势,而且这种
技术
也逐渐成熟。
DBA
只需要确定
Oracle
数据库
总的内存使用大小(
memory_target
),就会根据算法、负载不断调整实现自适应的内存分区调整。
作为
PGA
分配,
Oracle
推出的自动调控参数是
pga_aggregate_target
,表示所有会话的
PGA
总分配大小。如果不启用
PGA
自动分配,该参数值就是设置为
0
。
SQL> show parameter pga
NAME
TYPE
VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target
big integer 0
ü
Hash_multiblock_io_count
该参数表示在进行
Hash Join
连接操作的时候,一次可以读取的块个数。在最新的版本中,该参数已经变成了一个隐含参数。
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
2
FROM SYS.x$ksppi x, SYS.x$ksppcv y
3
WHERE x.inst_id = USERENV ('Instance')
4
AND y.inst_id = USERENV ('Instance')
5
AND x.indx = y.indx
6
AND x.ksppinm LIKE '%hash_multiblock%';
NAME
VALUE
DESCRIB
------------------------------ ---------- ------------------------------
_hash_multiblock_io_count
0
number of blocks hash join wil
l read/write at once
这个参数可以追溯到
Oracle 8i
时代,当时设置的默认值为
1
。在以后的版本中,通常设置为
0
。这个参数对
IO
影响重大,不同的硬件环境、系统负载下效果不同。所以,当设置为
0
的时候,
Oracle
是会每次自动计算该值。
作为我们来讲,最好不要进行该参数的设置。
4
、连接三模式
Hash Join
比较
Merge Sort Join
一个比较优势的地方,就是对
PGA
空间的有限使用上。但是,使用
PGA
毕竟是一种风险操作。因为
Hash Area
同
Sort Area
一样,在小表不能完全装入系统时,会调用
Temp
表空间的硬盘空间。这样,就会引起一些问题。
下面关于三种模式的阐述,
借鉴八神前辈的《
Oracle Hash Join
》(
http://www.alidba.net/index.php/archives/440
)。特此表示感谢。
针对不同的状态,
Oracle
分别有不同的模式对应。
Optimal
模式
这是我们进行
Hash Join
的最理想情况。驱动表(小表)生成的
Hash
数据集合可以完全存放在
Hash Area
的时候,我们称之为
Optimal
模式。
ü
首先找到驱动表,获取到驱动表。存放在
Hash_Area
中;
ü
在
Hash Area
中,对驱动表进行
Hash
操作,形成
Hash Bulket
,形成对应的分区信息。针对多个
Bulket
,同时形成一个
Bitmap
列表,做到
Bulket
与
Bitmap
位的联系;
ü
在各个
Bulket
中,分布着不同的数据行。如果连接列分布比较均匀,
Bulket
中数据也就比较均匀。如果
Bulket
中包括数据,对应该
Bulket
的
Bitmap
位上为
1
,否则为
0
;
ü
找被驱动表的每一列,将连接列值进行
Hash
处理。匹配
Bitmap
位,如果
Bitmap
为
0
,表示该列值没有存在,直接抛弃。否则进入
Bulket
进行精确匹配;
Onepass
模式
如果我们设置的
PGA
空间小,或者连接的小表体积就已经很大了,那么就会利用到临时表空间。具体处理,就是进行两次的
Hash
处理,在
Bulket
层面的上面建立
Partition
分区。
当进行
Hash
操作的时候,出现的情形是一部分的
Partition
在内存中,另一部分
Partition
被存放在
Temp
表空间上。
在进行连接匹配的时候,如果能够在
Bitmap
中确定到
Partition
在内存中,那么直接在内存中进行检索和精确匹配过程。否则从
Temp
表空间中将对应的
Partition
调取到内存中,进行匹配操作。
Multipass
模式
这是一种很极端的情况,如果
Hash Area
小到一个
Partition
都装不下。当进行
Hash
操作后,只有半个
Partition
能装入到
Hash Area
。
这种情况下,如果一个
Partition
匹配没有做到,还不能够放弃操作,要将剩下一半的
Partition
获取到进行
Hash Join
匹配。也就是一个
Partition
要经过两次的
Bitmap
匹配过程。
5
、结论
Hash Join
是一种效率很高,
CBO
时代很常见的连接方式。但是,相对于其他古典算法,
Hash Join
的综合效率很高,特别在海量数据时代。
查看全文
相关阅读:
PHP生成xml 无法识别或是无法读取或是浏览器不识别等问题
关于PHP 采集类
Centos7 下安装Docke
Git使用之设置SSH Key
yii2.0中Rbac 怎么添加超加管理员
Undefined index: HTTP_RAW_POST_DATA的解决办法
window下phpstudy的nginx配置虚拟主机
yii2.0中添加二维数组,多条数据。
预防onion比特币勒索病毒,如何快速关闭135,137,138,139,445端口
github与git之间怎么建立连接
原文地址:https://www.cnblogs.com/pekkle/p/6568852.html
最新文章
ceph 高级运维
lvs+dr模式(关键操作)
ip、ifconfig命令与IP(转)
ceph维护
公司冷备服务器1.100切换到1.99
(转)ceph 常用 运维命令--查看信息
(转)Centos7 修改硬件时间和系统时间
(转)win7批量创建用户
(转)公有云vr客户端tcp连接数太多造成 系统卡顿问题 [bittorrent tracker优化] -公有云常见网络问题及思路
实际经验+沟通表达能力强,协作能力强,这些甚至比专业技能更重要
热门文章
2015 Multi-University Training Contest 3 hdu 5317 RGCDQ
UVA 11419 SAM I AM
HDU 4366 Successor
UVA 12003 Array Transformer
UVALive 3211 Now or later
hdu 2767 Proving Equivalences
HDU 3844 Mining Your Own Business
CodeForces 445E DZY Loves Colors
2015 Multi-University Training Contest 4 hdu 5336 XYZ and Drops
2015 Multi-University Training Contest 4 hdu 5335 Walk Out
Copyright © 2011-2022 走看看