并行
查看并行度:
select table_name ,degree from dba_tables where table_name = '';
#———————————————————————————
关闭并行:
alter table xx.xx noparallel;
alter index xx.xx noparallel;
#———————————————————————————
并行度的选择
一般使用2的幂作为并行度,如2、4、8、16等,正常情况并行度不要设置太高,建议最多不要超过32。
特殊情况特殊对待,强悍的系统(比如exadata),
如果需要非常高的响应速度,并行度再多个几倍也不是问题。并行高的时候并发就要减少,否则可能会耗光并行资源。
#———————————————————————————#
使用例:
创建大表
create table test parallel 16 as select .... from t1,t2 where .....;
alter table test noparallel;
#———————————————————————————
创建或重建索引
create index idx_test on table_A(name) parallel 8;
alter index idx_test noparallel;
#———————————————————————————
表分析degree=>6
exec dbms_stats.gather_table_stats('RES_ANHUI','ADDR_SEGM',method_opt=>'for all indexed columns size 254',granularity=>'ALL',cascade=>TRUE);
exec dbms_stats.gather_table_stats('RES_ANHUI','ADDR_SEGM',partname=>'SYS_P101',estimate_percent=>1,no_invalidate=>FALSE,degree=>6,granularity=>'PARTITION',cascade=>true);
exec dbms_stats.gather_table_stats('RES_ANHUI','ADDR_SEGM',partname=>'SYS_P102',estimate_percent=>1,no_invalidate=>FALSE,degree=>6,granularity=>'PARTITION',cascade=>true);
exec dbms_stats.gather_table_stats('RES_ANHUI','ADDR_SEGM',partname=>'SYS_P103',estimate_percent=>1,no_invalidate=>FALSE,degree=>6,granularity=>'PARTITION',cascade=>true);
exec dbms_stats.gather_table_stats('RES_ANHUI','ADDR_SEGM',partname=>'SYS_P104',estimate_percent=>1,no_invalidate=>FALSE,degree=>6,granularity=>'PARTITION',cascade=>true);
#———————————————————————————#
并行hint的写法
/*+ parallel(n) */
#———————————————————————————
只要在整个sql的任何一个关键字
(select、update、insert、delete、merge)
后面出现一次
parallel(n)
那么整个SQL相关的表,都会使用并行
select /*+ parallel(8) */…from t1,t2…
#———————————————————————————
对指定的表开并行
select /*+ parallel(a 4) parallel(b 4) */ … from t1,t2…
例如对t1表开并行
select /*+ parallel(t1 8) */count(*) from demo t1,test t2 where t1.object_id = t2.object_id;
#———————————————————————————
索引:(括号内可以是空格也可以是逗号)
select /*+ parallel_index(demo idx_id_demo 8) */object_id from demo where object_id > 1000;
#———————————————————————————#
DML并行:
INSERT、DELETE、UPDATE还有MERGE
#———————————————————————————
这种只会在后面select开并行,dml是默认不开并行的
insert /*+ parallel(4) */ into t1 select .... from ....;
#———————————————————————————
所以:必须在session级别通过下面命令开启
alter session enable parallel dml;
活着用force的语法,可以使下面的dml即使不用parallel的hint,也会使用并行度为n的并行。
alter session force parallel dml parallel n;
开启了DML的并行后,接下来的DML语句将会产生一个表锁,
在commit之前,
当前session 不能对该表做查询和dml操作,其他session也不能对该表做DML操作。
#———————————————————————————
所以:流程应为:
alter session enable parallel dml;
your dml;
commit;
alter session disable parallel dml;
或者
alter session force parallel dml parallel 1;
#———————————————————————————#
备注:
对于提到的表的情况,并不是指这个表内具体有多少数据,
比如一个表有1 亿行记录,返回一行数据,那么肯定是不能用并行的,效率最高的肯定是索引;
一个表只有100 万行,但是返回了20 万行记录,那么用索引肯定效率低,可以考虑并行;
总的来说,表的分析是指经过where 条件过滤后返回的记录,
如果返回的数据很少,哪怕表的数据量很大,那么都适合使用索引,
如果表的记录数相对不大,返回的记录数多,那么可以考虑使用并行的全表扫描。