需要打开计时器的话可以参考
set timing on;
在开始之前需要强调的是
任何并发操作都是以硬件换速度, 如果没有足够的硬件不要轻易使用并发,另外如果是大访问量的网站系统请慎用,数据库并发查询一般还是用在夜晚的大批量batch批处理上
1. 直接改表
ALTER TABLE INO_ONCONFIG.LOOKUP_OPTIONS PARALLEL 4;
要关闭的话使用直接NOPARALLEL参数或者直接设置线程数为1好像也可以
ALTER TABLE INO_ONCONFIG.LOOKUP_OPTIONS NOPARALLEL;
ALTER TABLE INO_ONCONFIG.LOOKUP_OPTIONS PARALLEL 1;
2. 使用hint
需要注意的是如果需要指定schema名的话hint的时候需要把schema名去掉
select /*+ parallel(LOOKUP_OPTIONS 8) */ count(*) from INO_ONCONFIG.LOOKUP_OPTIONS;
下面我使用一个关联查询的sql来看看并行与非并行的区别
(我这里并发的消耗要比直接全表扫描join更大)
EXPLAIN PLAN FOR select * from INO_OUTAGES.OUTAGE o join INO_OUTAGES.BASE_LOOKUP b on o.id=b.OUTAGE_ID; SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY(‘PLAN_TABLE’));EXPLAIN PLAN FOR select /*+ parallel(o 4) */ /*+ parallel(b 4) */ * from INO_OUTAGES.OUTAGE o join INO_OUTAGES.BASE_LOOKUP b on o.id=b.OUTAGE_ID; SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY(‘PLAN_TABLE’)); |


PX 进程: Parallel Execution Slaves
Parallel to Serial(P->S): 并发到串行
Parallel to Parallel(P->P):并发到并发
Parallel Combined with parent(PCWP): 同一个从属进程执行的并行操作,同时父操作也是并行的。
Parallel Combined with Child(PCWC): 同一个从属进程执行的并行操作,子操作也是并行的。
Serial to Parallel(S->P): 串行到并发
用户进程发起请求之后, oracle会使用一个QC进程(Query Coordinator)来协调这个用户进程与oracle进程之间的工作
它会决定这个请求的并发度,控制执行过程,汇总结果等 ( 上图中的PX COORDINATOR)
一般来说你只会有一个QC, 不过如果使用了类似UNIONALL这样的操作,就会出现多个QC
每个QC都包含一个树形结构, 这个树包含若干DFO节点(Data Flow Operator) , DFO是可以并行执行的单元, QC持有一到两组QSS(Query Slaves Set),每个QSS包含若干QS(Query Slaves),QSS会扮演生产者和消费者的角色,(每个QSS可能同为生产者,也可能同为消费者,也可能一个生产者一个消费者), 我们通常所说的并行度指的是一组QSS里并行的QS个数,所以如果oracle使用了两组QSS,那么实际运行的线程数会是并行度的两倍
TQ(table queue), 意为表队列。它是一个逻辑上的概念。在并行执行中,用TQ来实现query slave set 之间以及query slave set 和QC之间数据的传递和重新分布。可以简单认为就是存储并行执行过程中的中间结果的临时表
简单归纳一下
oracle进程
-> 启动1个QC或者多个QC
-> 每个QC = 一个DFO树
-> 每个QC = 最多2个QSS (查看TQ列)
-> 每个QSS = 若干QS
所以上图中
启动一个QC,也就是一个DFO树( 参考id 1 )
有两组QSS(TQ列的Q10,01和Q10,02) ( id 2,3,4,5 为Q10,02 id 9,10,11,12为Q10,01)
Q10,01为生产者 (它在执行TABLE ACCESS FULL和 PX BLOCK ITERATOR id 11,12) , Q10,01 先以并行的方式对OUTAGE table进行了全表扫描
同时, Q10,02在一开始也作为生产者扫描了BASE_LOOKUP 表, 然后转为消费者在id 03 处对两个结果集进行了join, 然后输出了合并后的结果
为了观察的更细致一些使用union all关键字可以得到两个QC的结果
EXPLAIN PLAN FOR select /*+ parallel(o 4) */ /*+ parallel(b 4) */ o.id,b.OUTAGE_ID,o.OUTAGE_TYPE from INO_OUTAGES.OUTAGE o left join INO_OUTAGES.BASE_LOOKUP b on o.id=b.OUTAGE_ID union all select /*+ parallel(o 4) */ /*+ parallel(h 4) */ h.id,h.OUTAGE_ID,o.OUTAGE_TYPE from INO_OUTAGES.OUTAGE o left join INO_OUTAGES.HISTORY h on o.id=h.OUTAGE_ID ; SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY(‘PLAN_TABLE’)); |
