一个表50MB 

一个表10GB 

50M表做驱动表,放在PGA里

这时候慢在对对 10g 的全表扫描

对10个G扫描块 需要开并行

我有这样一个算法 

一个进程 读 50mb 

8进程 来 扫描 10gb 

一个 进程扫描 1.25gb 

50MB 都分发到 8个进程

超大表和小表之间做HASH JOIN,一般会启用用并行,ORACLE在并行HASH JOIN的时候会用到很多技术,比如 HASH HASH, 或者BROADCAST

对于超大表和小表做HASH JOIN,一定要让小表进行广播(Broadcast),通常情况下CBO会选择正确,但是如果统计信息不准,或者基数计算错误CBO选择了 HASH HASH join,这个时

候就很慢,观察现象就是它在做direct path write temp,这个时候就可以用HINT PQ_DISTRIBUTE 进行调整

PQ_DISTRIBUTE(驱动表 None, Broadcast) 如果外层表很小(HASH_AJ),
这个时候可以用 PQ_DISTRIBUTE(驱动表 Broadcast,None) 下面就是一个具体的例子, F 是一个超大表 T 是一个小表 SQL&get; explain plan for select /*+ parallel(f 8) parallel(t 8) use_hash(t,f) full(f) full(t) PQ_DISTRIBUTE(f HASH, HASH) */ *
2 from crs_data_fct f
3 JOIN crs_time_perd_fdim t ON t.TIME_PERD_ID = f.TIME_PERD_ID; Explained. Elapsed: 00:00:00.83
SQL&get; select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 353396990 ---------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 239M| 696G| 8371 (20)| 00:01:58 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10002 | 239M| 696G| 8371 (20)| 00:01:58 | | | Q1,02 | P-&get;S | QC (RAND) |
|* 3 | HASH JOIN BUFFERED | | 239M| 696G| 8371 (20)| 00:01:58 | | | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,02 | PCWP | |
| 5 | PX SEND HASH | :TQ10000 | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,00 | P-&get;P | HASH |
| 6 | PX BLOCK ITERATOR | | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,00 | PCWC | |
| 7 | TABLE ACCESS STORAGE FULL| CRS_TIME_PERD_FDIM | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 8 | PX RECEIVE | | 239M| 673G| 8267 (19)| 00:01:56 | | | Q1,02 | PCWP | |
| 9 | PX SEND HASH | :TQ10001 | 239M| 673G| 8267 (19)| 00:01:56 | | | Q1,01 | P-&get;P | HASH |
| 10 | PX PARTITION LIST ALL | | 239M| 673G| 8267 (19)| 00:01:56 | 1 | 951 | Q1,01 | PCWC | |
| 11 | TABLE ACCESS STORAGE FULL| CRS_DATA_FCT | 239M| 673G| 8267 (19)| 00:01:56 | 1 | 951 | Q1,01 | PCWP | |
--------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 3 - access("T"."TIME_PERD_ID"="F"."TIME_PERD_ID") Note
-----
- dynamic sampling used for this statement (level=6) 27 rows selected. SQL&get; explain plan for select /*+ parallel(f,8) parallel(t 8) use_hash(t,f) full(f) full(t) PQ_DISTRIBUTE(t None, Broadcast) */ *
2 from crs_data_fct f
3 JOIN crs_time_perd_fdim t ON t.TIME_PERD_ID = f.TIME_PERD_ID; Explained. SQL&get; select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 271674260 ---------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 239M| 696G| 8371 (20)| 00:01:58 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 239M| 696G| 8371 (20)| 00:01:58 | | | Q1,01 | P-&get;S | QC (RAND) |
|* 3 | HASH JOIN | | 239M| 696G| 8371 (20)| 00:01:58 | | | Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,01 | PCWP | |
| 5 | PX SEND BROADCAST | :TQ10000 | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,00 | P-&get;P | BROADCAST |
| 6 | PX BLOCK ITERATOR | | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,00 | PCWC | |
| 7 | TABLE ACCESS STORAGE FULL| CRS_TIME_PERD_FDIM | 15808 | 1636K| 10 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 8 | PX PARTITION LIST ALL | | 239M| 673G| 8267 (19)| 00:01:56 | 1 | 951 | Q1,01 | PCWC | |
| 9 | TABLE ACCESS STORAGE FULL | CRS_DATA_FCT | 239M| 673G| 8267 (19)| 00:01:56 | 1 | 951 | Q1,01 | PCWP | |
--------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 3 - access("T"."TIME_PERD_ID"="F"."TIME_PERD_ID") Note
-----
- dynamic sampling used for this statement (level=6) 25 rows selected. hints:PQ_DISTRIBUTE(小表 None, Broadcast)

OLAP 大表和小表并行hash join的更多相关文章

  1. Oracle 表的连接方式(2)-----HASH JOIN的基本机制3

    HASH JOIN的模式 hash join有三种工作模式,分别是optimal模式,onepass模式和multipass模式,分别在v$sysstat里面有对应的统计信息: SQL> sel ...

  2. 并行HASH JOIN小表广播问题

    SQL语句: SELECT /*+parallel(t1 16)*/ T1.DATA_DATE, T1.ACCT_NO, T1.ACCT_ORD, T1.ACCT_NO_PK, T1.ACCT_BAL ...

  3. switch...case...语句分析(大表跟小表何时产生)

    一.switch...case...的格式 switch(表达式) { case 常量表达式1: 语句; break; case 常量表达式2: 语句; break; case 常量表达式3: 语句; ...

  4. Oracle 表的连接方式(2)-----HASH JOIN的基本机制2

    Hash算法原理 对于什么是Hash算法原理?这个问题有点难度,不是很好说清楚,来做一个比喻吧:我们有很多的小猪,每个的体重都不一样,假设体重分布比较平均(我们考虑到公斤级别),我们按照体重来分,划分 ...

  5. Oracle 表的连接方式(2)-----HASH JOIN的基本机制1

    我们对hash join的常见误解,一般包括两个: 第一个误解:是我们经常以为hash join需要对两个做join的表都做全表扫描 第二个误解:是经常以为hash join会选择比较小的表做buil ...

  6. 小表驱动大表, 兼论exists和in

    给出两个表,A和B,A和B表的数据量, 当A小于B时,用exists select * from A where exists (select * from B where A.id=B.id) ex ...

  7. 【Spark调优】小表join大表数据倾斜解决方案

    [使用场景] 对RDD使用join类操作,或者是在Spark SQL中使用join语句时,而且join操作中的一个RDD或表的数据量比较小(例如几百MB或者1~2GB),比较适用此方案. [解决方案] ...

  8. Oracle的大表,小表与全表扫描

    大小表区分按照数据量的大小区分: 通常对于小表,Oracle建议通过全表扫描进行数据访问,对于大表则应该通过索引以加快数据查询,当然如果查询要求返回表中大部分或者全部数据,那么全表扫描可能仍然是最好的 ...

  9. MySql 小表驱动大表

    在了解之前要先了解对应语法 in 与 exist. IN: select * from A where A.id in (select B.id from B) in后的括号的表达式结果要求之输出一列 ...

随机推荐

  1. 关于MySQL的各种总结

    https://blog.atime.me/note/mysql-summary.html 总结使用MySQL过程中遇到的各种问题和一些有用的资源,配置等等.将之前的若干篇零散的文章汇总到一起,备忘. ...

  2. Qt 学习之路:文件

    文件操作是应用程序必不可少的部分.Qt 作为一个通用开发库,提供了跨平台的文件操作能力.从本章开始,我们来了解下 Qt 的文件以及输入输出的功能,也就是 I/O 系统. Qt 通过QIODevice提 ...

  3. MySQL Error Handling in Stored Procedures---转载

    This tutorial shows you how to use MySQL handler to handle exceptions or errors encountered in store ...

  4. linux共享windows资料

    linux 只有NTFS格式不能访问,其的都可以.1.用fdisk -l 查看分区表.2.然后用mount -t vfat /mnt/hda1 /dev/hda1 就可以了./mnt/hda1是一普通 ...

  5. 如何自定义echarts主题

    上一篇,选择echarts原有的主题样式,那么如何自定义自己的主题 与选择原有主题类似 1.echarts官网地址http://echarts.baidu.com/echarts2/doc  在工具中 ...

  6. POJ - 3608 Bridge Across Islands【旋转卡壳】及一些有趣现象

    给两个凸包,求这两个凸包间最短距离 旋转卡壳的基础题 因为是初学旋转卡壳,所以找了别人的代码进行观摩..然而发现很有意思的现象 比如说这个代码(只截取了关键部分) double solve(Point ...

  7. Eclipse 打开时“发现了以元素'd:skin'”开头的无效内容。此处不应含有子元素(转)

    打开 Eclipse 时,如图所示: 解决办法: 把有问题的 devices.xml 文件删除,再把 sdk 里面 tools\lib 下的这个文件拷贝到你删除的那个文件夹里,重启 eclipse 就 ...

  8. Delphi ControlCount和ComponentCount的区别

    ComponentCount指打开的窗体所拥有的控件个数,包含所有子组件.孙组件(子组件内的子组件) 如上图,Form1的ComponentCount是13,而Panel1的ComponentCoun ...

  9. 复制构造函数2——深入理解

    //如果不显示定义复制构造函数,编译会出错,原因是:在创建对象s2时,调用默认复制构造函数并用对象s1对其进行初始化,致使s2中指针 //与s1中指针指向同一储存空间,当一个对象生命周期结束后调用析构 ...

  10. linux 日常命令(磁盘空间)

    df –hl 在windows下可以很方便的查看磁盘空间的.但是到了Linux查看磁盘空间,你可能就有点摸不着头脑了,呵呵.不要急,我这就要给你解决这个问题. Df命令是Linux查看磁盘空间系统以磁 ...