通常情况下,数据库任务处理是单进程的,即一个任务的所有内容都由一个进程完成,当单个任务较大时,存在效率低下的问题。
目录
一、并行执行概念
1.1 并行执行适用场景
1.2 进程池
1.3 并行执行的过程
二、开启并行执行
2.1 手动设置并行度
2.1.1 在对象级别指定并行度
2.1.2 在会话级别指定并行度
2.1.3 在SQL中使用提示(hint)指定并行度
2.2 默认(自动)并行度
2.3 并行语句队列
三、并行执行设置参数
并行执行是指在处理SQL任务时,例如扫描表、表连接及各种DDL操作,都可以利用多个进程并行处理,每个进程处理原任务的一小部分,从而提升响应速度。
现代计算机通常都具有多个CPU,这为并行执行提供了基础。并行执行虽然可以提升效率,但并不是任何场景都使用的。并行执行其实是通过压榨硬件来充分利用多个CPU和I/O资源,从而提升任务的处理速度。
在启用并行执行前需考虑系统是否符合下列条件:
从特性上看,并行执行很擅长处理大任务,因此其通常在数据库仓库或决策支持系统上使用。
对于任务很小且高并发的环境(典型的OLTP系统),或者系统的负载本来就很高了(硬件已经被充分利用),并行执行不但不能提升性能,反而可能会增加系统负担。但凡事无绝对,对于OLTP系统上一些较大的任务,我们也可以选择性的利用并行执行来提升速度。
当实例启动时,Oracle会根据参数parallel_min_servers设定的值,创建一定数量的并行执行服务器进程(Parallel Exection servers PX),这些进程专门用来处理并行任务。
这些进程被放入一个进程池(Parallel Execution Server Pool)保存,Oracle会保证池中进程的数量不低于参数parallel_min_servers。当用户需要执行并行任务时,会从池中获取进程,当执行完后又会将进程放回池中。
Oracle会也根据负载来动态创建/销毁池中的进程,但不超过parallel_max_servers限制,保证池中的进程数量在[parallel_min_servers, parallel_max_servers]区间内变化。
当执行并行任务时:
如果服务器的负载很高,进程池已经达到最大值,且协调进程依然无法从池中获得进程。那么并行执行将会退化为传统的串行执行。
在开启并行执行特性时,我们可以指定用来处理任务进行数量。而处理单一任务的进程数量叫做并行度(Degree of Parallelism DOP)。例如我从进程池获取了4个进程来执行一个SQL,那么并行度就是4。
在需要并行执行时,我们可以:
你可以显式用 alter table 的 parallel 子句为表或索引指定并行度(这里的表tab1和tab2是预先建好的):
alter table tab1 parallel 4;
alter table tab2 parallel 8;
上面的语句为tab1指定了并行度为4,tab2并行度为8。如果SQL同时访问了tab1和tab2,那么并行度为8(以高的表为准)。
在创建对象时,也可以使用parallel子句来指定并行度。下面在tab1的name列上新建索引,指定并行度为4:
create index idx_tab1_name on tab1(name) parallel 4;
取消一个对象的并行特性,用alter … noparallel 即可:
alter table tab1 noparallel;
你也可以在会话级别为某类语句开启并行,会话级别的并行设置将会覆盖对象级别的并行设置:
语法:alter session (enable/disable/force) parallel (dml/ddl/query) (parallel n);
例如,在当前会话级别为所有查询开始并行:
alter session enable parallel query;
使用force选项时,会强制后续语句使用并行执行,并且用指定的并行度覆盖默认并行度。如果未指定,则会使用默认并行度,下面SQL为会话的DDL开启并行,并指定并行度为4:
alter session force parallel ddl parallel 4;
当开启force ddl时,会话创建的所有表都会使用指定的并行度,就像在create table语句中使用 parallel N 子句一样。
在会话级别开启并行度后,可以通过v$session表中的pdml_status,pddl_status, pq_status来查看DML,DDL, QUERY 的会话并行状态,可能的状态有disabled/enabled/forced。
select username,pdml_status,pddl_status,pq_status from v$session where username='VINCENT';
在SQL中使用提示也可以指定语句并行度:
select /*+parallel(tab1,4)*/ * from tab1;
上面的SQL使用提示 /*+parallel(table_name, DOP)*/ 来指定并行度为4。
同样你也可以使用提示 /*+noparallel(table_name)*/ 来禁用并行执行。
select /*+noparallel(tab1)*/ * from tab1;
除了select,当对较大的表进行insert, delete, update, merge操作时,也可以利用并行执行来提升响应速度:
update /*+parallel(tab1,4)*/ tab1 set name='Vincent';
如果不知道并行度设置为多少合适,可以不指定并行度,这样Oracle会自动决定并行度。上面设置并行的语句中,我们去掉parallel后的数字,oracle将自行决定并行度。
alter table tab1 parallel;
通常情况下,自动并行度=单个CPU并行线程*CPU数量*实例数(如果是单实例,实例数就是1)
注:自定并行度特性只有当参数parallel_degree_policy设置为limited/auto/adaptive时才生效。
并行语句队列(parallel statement queuing)是指当一个SQL需要并行执行,但是没有足够的并行资源时(当前SQL需要的并行资源加上已被使用的资源超过parallel_servers_target参数设定值),Oracle会将其放入队列等待,当有足够的并行资源时,再处理该语句。
注:并行语句队列特性只有当参数 parallel_degree_policy设置为auto/adaptive时才生效。
关于并行执行的主要控制参数如下,通过修改参数的值,可以控制并行执行的特性:
下面依次解释各个参数的作用:
parallel_degree_policy, 用来控制自动并行度,并行队列,in-memory并行执行特性的开启和关闭,有下列4个选项:
parallel_degree_limit,当oracle自动决定并行度时,必须有一个上限,此参数即是控制自动并行度的最大值:
parallel_min_degree,用来设置自动并行度时的最小并行度,默认值为1。
parallel_min_time_threshold,当SQL的预计执行时间超过此参数设定的时间时,才会启用并行执行。因此一些小任务(预计执行时间很短)不会触发并行执行特性,默认为auto,你也可以指定一个数字。
parallel_servers_target 用来控制何时将语句加入并行语句队列。如果当前SQL需要的并行资源加上已被使用的并行资源超过该参数的值(需要小于parallel_max_servers的值),则将语句加入并行语句队列等待。例如该参数设置为30,目前已被使用的并行进程数为26,此时某SQL过来请求8个并行进程,那么8+26>30,该SQL将被加入并行语句队列等待。
parallel_min_servers 指定实例启动时创建的初始并行进程数。
parallel_max_servers 指定实例可以创建的最大并行进程数。