通常情况下,数据库任务处理是单进程的,即一个任务的所有内容都由一个进程完成,当单个任务较大时,存在效率低下的问题。

目录

一、并行执行概念

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操作,都可以利用多个进程并行处理,每个进程处理原任务的一小部分,从而提升响应速度。

1.1 并行执行适用场景

现代计算机通常都具有多个CPU,这为并行执行提供了基础。并行执行虽然可以提升效率,但并不是任何场景都使用的。并行执行其实是通过压榨硬件来充分利用多个CPU和I/O资源,从而提升任务的处理速度。

在启用并行执行前需考虑系统是否符合下列条件:

  • 处理的数据集较大,响应时间很重要。
  • CPU的正常负载很低。
  • I/O空闲带宽较大。
  • 系统有足够的内存,支持并发的排序、I/O缓存等操作。

从特性上看,并行执行很擅长处理大任务,因此其通常在数据库仓库或决策支持系统上使用。

对于任务很小且高并发的环境(典型的OLTP系统),或者系统的负载本来就很高了(硬件已经被充分利用),并行执行不但不能提升性能,反而可能会增加系统负担。但凡事无绝对,对于OLTP系统上一些较大的任务,我们也可以选择性的利用并行执行来提升速度。

1.2 进程池

当实例启动时,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]区间内变化。

1.3 并行执行的过程

当执行并行任务时:

  1. 发起并行执行的用户会话通常会作为并行执行的协调进程(Parallel Execution Coordinator),并将任务拆分为若干部分(granule)。
  2. 协调进程会根据任务并行度(Degree of Parallelism DOP)从进程池中获得并行执行进程(Parallel Execution servers PX)。
  3. 每个并行进程会处理任务的一部分(以granule为单位),并将结果返回给协调进程。如果部分任务不能并行执行(例如最后的sum),则由协调进程处理。
  4. 协调器负责各个并行进程结果的汇总,处理,并将最终结果返还给用户。

如果服务器的负载很高,进程池已经达到最大值,且协调进程依然无法从池中获得进程。那么并行执行将会退化为传统的串行执行。

二、开启并行执行

在开启并行执行特性时,我们可以指定用来处理任务进行数量。而处理单一任务的进程数量叫做并行度(Degree of Parallelism DOP)。例如我从进程池获取了4个进程来执行一个SQL,那么并行度就是4。

2.1 设置并行执行

在需要并行执行时,我们可以:

  • 设置对象的并行度。
  • 在会话级别设定并行度。
  • 在语句中通过hint来指定并行度,拥有最高优先级。

2.1.1 在对象级别指定并行度

你可以显式用 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;

2.1.2 在会话级别指定并行度

你也可以在会话级别为某类语句开启并行,会话级别的并行设置将会覆盖对象级别的并行设置:

语法: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';

2.1.3 SQL中使用提示(hint)指定并行度

在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';

2.2 默认(自动)并行度

如果不知道并行度设置为多少合适,可以不指定并行度,这样Oracle会自动决定并行度。上面设置并行的语句中,我们去掉parallel后的数字,oracle将自行决定并行度。

alter table tab1 parallel;

通常情况下,自动并行度=单个CPU并行线程*CPU数量*实例数(如果是单实例,实例数就是1)

注:自定并行度特性只有当参数parallel_degree_policy设置为limited/auto/adaptive时才生效。

2.3 并行语句队列

并行语句队列(parallel statement queuing)是指当一个SQL需要并行执行,但是没有足够的并行资源时(当前SQL需要的并行资源加上已被使用的资源超过parallel_servers_target参数设定值),Oracle会将其放入队列等待,当有足够的并行资源时,再处理该语句。

注:并行语句队列特性只有当参数 parallel_degree_policy设置为auto/adaptive时才生效。

三、并行执行设置参数

关于并行执行的主要控制参数如下,通过修改参数的值,可以控制并行执行的特性:

  • parallel_degree_policy(并行策略开关)
  • parallel_degree_limit(自动并行度最大限制)
  • parallel_min_degree(自动并行度最小限制)
  • parallel_min_time_threshold(并行执行门槛时间)
  • parallel_servers_target(并行语句队列的使用)
  • parallel_min_servers(初始并行进程数)
  • parallel_max_servers(最大并行进程数)

下面依次解释各个参数的作用:

parallel_degree_policy, 用来控制自动并行度,并行队列,in-memory并行执行特性的开启和关闭,有下列4个选项:

  • manual,禁用自动并行度,并行语句队列和in-memory并行执行,只有 "显式设置对象的并行度" 或 "在SQL中使用并行提示(hint)" 才会启用并行执行,这也是默认设置。
  • limited,启动自动并行度(启用并行执行且未指定并行度),但禁用并行语句队列和in-memory并行执行,如果表显式指定了并行度,则会采用指定的并行度。
  • auto,所有的语句都将采用自动并行度,同时启用并行语句队列和in-memory并行执行特性。
  • adaptive,和auto类似,但是会有额外的性能反馈。

parallel_degree_limit,当oracle自动决定并行度时,必须有一个上限,此参数即是控制自动并行度的最大值:

  • CPU,指定最大并行度受CPU数量限制,自动并行度=单个CPU并行线程*CPU数量*实例数
  • auto,和CPU相同
  • IO,最大并行度受系统IO能力限制,自动并行度=系统最大吞吐量/单进程带宽,你需要调用dbms_resource_manager.calibrate_io来使用此设置。
  • integer,手动指定一个整数作为自动并行度的限制。

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 指定实例可以创建的最大并行进程数。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐