Oracle 并行 QC PX

概念 串行执行: 串行执行时候,sql语句由一个server process处理(既只运行在一个cpu上),所以sql语句所能使用的资源受cpu限制,除去异步i/o外server process 处理cpu操作时,不可访问disk。 并行处理: 就是多个slave process一起处理同一个sql语句  

概念


串行执行:串行执行时候,sql语句由一个server process处理(既只运行在一个cpu上),所以sql语句所能使用的资源受cpu限制,除去异步i/o外server process处理cpu操作时,不可访问disk。
并行处理:就是多个slave process一起处理同一个sql语句,server process充当query coordinator(创建slave process,分配任务,收集合并slave process传的结果返回给client)。
并行执行工作粒度:
1.分区粒度(paratition granule):一个分区 或一个子分区 为一个工作内容被分配(分区segment上)。就是操作PX BLOCK ITERATOR。
2.块范围粒度(block range granule):segment上一个范围内的block,运行时动态定义(不是parse时)。就是操作PX PARTION ITERATOR。---- oracle不是访问数据后才知道数据在那一块的(SGA, CBC chain),rowid已经记录了,所以发出平行时,oracle可以分派几个px 去几个block处理。

注释:
*oracle倾向于block range granule,因为block range granule可以让slave process们得到的工作量比较平均,而分区粒度 有可能会使有的slave process得到的分区的工作量很大,导致时间响应更长会影响到并行执行的总效率。  分区不均衡

*sql语句执行2个或2个以上独立的操作(比如,非相关性操作join,scan(如全表扫描等)&order by这样会使用2组slave process,一组scan,一组order by)
*按scan&order by这个例 子,2组slave process,第一组select,那么select中的并行(slave process 操作)叫操作内并行,即单个操作内并行化。那么scan与order by就是2次操作内并行。
*2组slave process用来执行一个sql语句 叫操作间并行(组1 sacn ,组2 orderby 之间操作就是操作间并行)。
*操作间并行时,会有多组slave process通,例如组1scan数据 给组2orderby,组1就是生产者(producer),组2就是消费者(consumer),按生产者与消费者执行的。

不同操作,就会选择不同的分配(数据)记录方式给另一个操作:
1.广播:每个生产者发送所有数据给消费者
2.range:生产者将执定范围的记录发给不同的消费者,会应用动态范围分区决定哪条记录给哪个消费者(对于orde by操作根据order by子句中字段range分区)
3.loop:记录会被平均分给每个消费者(即生产者每loop循环一次,就给一个消费者发一条记录)
4.hash:生产者用hash函数发送数据给消费者,动态应用hash分区来决定哪条记录给哪个消费者(对于group by根据group by子句使用的字段进行hash )
5.qc随机:每个生产者将所有记录发给query coordinator(随机),这是常用方法
6.qc顺序:每个生产者将所有记录发给query coordinator(顺序很重要),并行orderby用这个给query coordinator(server process)发送数据

#上面的广播方法就是执行计划中 px send qc(random/order)操作或是px send(qc 随机)操作 , 其父操作就是px coordator(查询调度)。

上面的range/hash/loop就是执行计划中px send qc range/hash/loop 操作 ,其父操作就是px recive(接收者,消费者)。

并行操作间关系(执行计划中in-out部分)
p-s:并行发送数据给串行
p-p:(有2组slaves process时使用),一个并行操作将数据发送给另一个并行操作
pcwp:相同slave process并行执行一个操作及其父操作,无通讯
pcwc:相同slave process并行执行一个操作及其子操作,无通讯
s-p:串行发送数据给并行,效率差(1.单一进程产生数据没有多个进程消费数据快,消费者花很多时间等数据而不是处理数据;2.串行执行操作和并行执行操作发送数据有一些不必要的通讯)

参数控制并行:
1.parallel_min_servers:

instance 启动数据库实例时就会自动创建的slaves process数量,这样当server process请求时候就不需要重新创建了,直接使用就可以。当server process请求的数量超过这个设置值时,就会创建新的slave process,新创建的在使用完成后会在slave process pool(oracle会管理一个slave process pool,query coordinator process既server process从这个pool中请求slave process,sql语句开始使用,使用后slave process返回pool)。

保存5分钟若还未人使用 就释放,所以 参数parallel_min_servers控制这个pool中启始slave process数量,defalut 0,表示需要时候才创建。
什么时候需要修改该参数:一般在出现os thread startup 这个event(表示sql语句花时间等待slave process)才修改这个值


2.parallel_max_server:

控制pool中slave process最大数量(可以设置成cpu_count ,8-10倍)。

parallel_adaptive_multi_user (为boolean 类型的参数)为TRUE (10G default为TRUE)时,仅允许有限数目的用户按默认的并行程度运行。

这个限度由_parallel_adaptive_max_users控制。 _parallel_adaptive_max_users表示maximum number of users running with default DOP。例如,_parallel_adaptive_max_users为 2,即 指定 现在显示为2个USER。

#查看server process pool状态
SQL> select * from v$px_process_sysstat where upper(statistic) like ‘SERVER%’;

STATISTIC VALUE
—————————— ———-
Servers In Use 0~~使用的
Servers Available 2~~
Servers Started 2~~~启动过几个
Servers Shutdown 0
Servers Highwater 2~~~最高到达
Servers Cleaned Up 0
Server Sessions 2

7 rows selected.

*sga中有一个table queue内存给消费者发送数据,每对(生产者&消费者)对应一个table queue处理2组从属进程间通信,table queue 可以放在shared pool,也可以large pool
其实table queue就是 px msg pool),当10G SGA_TARGET>0 or 11g memory_target>0时 都是存在large pool,parallel_automatic_tuning=true放在large pool,10G 默认为TRUE,11g
默认就是放在large pool,parallel_automatic_tuning在11G已经废弃向后兼容保留了(The PARALLEL_AUTOMATIC_TUNING parameter is deprecated. It is retained for backward compatibility only.)

关于这个parallel_automatic_tuning更详细的说明
When PARALLEL_AUTOMATIC_TUNING is set to true, Oracle determines the default values for parameters that control parallel execution. In addition to setting this parameter, you must specify the PARALLEL clause for the target tables in the system. Oracle then tunes all subsequent parallel operations automatically.

If you used parallel execution in a previous release and are now enabling PARALLEL_AUTOMATIC_TUNING, then you should reduce the amount of memory allocated from the shared pool to account for the decreased demand on that pool. This memory will now be allocated from the large pool, and will be computed automatically if LARGE_POOL_SIZE is not specified.

As part of the automatic tuning, Oracle will enable the PARALLEL_ADAPTIVE_MULTI_USER parameter. You can override any of the system-provided defaults if desired.

每个table queue由3个buffer (块)组成,在rac里为4个。每个buffer大小由parallel_execution_message_size控制,默认为2152bytes,parallel_automatic_tuning=true,parallel_execution_message_size=4096 bytes。
可以设置大点16k,32k,64K(内存要足够)

#########large pool size
large_pool_size>=parallel_max_servers^2.parallel_execution_message_size.3(rac .4)

SQL> select * from v$sgastat where upper(name)=’PX MSG POOL’;

POOL NAME BYTES
———— ————————– ———-
large pool PX msg pool 902160

所以可以认为table queue就是px msg pool

SQL> select pool,name ,bytes/1024/1024/1024 from v$sgastat where upper(pool) like ‘%LARGE%’;

POOL NAME BYTES/1024/1024/1024
———— ————————– ——————–
large pool PX msg pool .000840202
large pool free memory .003066048

并行概念

首先,Oracle会创建一个进程(server process充当query coordinator QC(创建slave process,分配任务,收集合并slave process传的结果返回给client))用于协调并行服务进程之间的信息传递,这个协调进程将需要操作的数据集(例如表的数据块)分割成很多部分,称为并行处理单元,然后并行协调进程给每个并行进程分配一个数据单元。例如有四个并行服务进程,它们就会同时处理各自分配的单元,当一个并行服务进程处理完毕后,协调进程就会给它们分配另外的单元,如此反复,直到表上的数据都处理完毕,最后协调进程负责将每个小的集合合并为一个大集合作为最终的执行结果,返回给用户。并行处理的机制实际上就是把一个要扫描的数据集分成很多小数据集,Oracle会启动几个并行服务进程同时处理这些小数据集,最后将这些结果汇总,作为最终的处理结果返回给用户。

这种数据并行处理方式在OLAP系统中非常有用,OLAP系统的表通常来说都非常大,如果系统的CPU比较多,那么可以让所有的CPU共同来处理这些数据,效果就会比串行执行要好得多。对于OLTP系统,通常而言,并行并不合适,原因是OLTP系统上几乎在所有的SQL操作中,数据访问路径基本上以索引访问为主,并且返回结果集非常小,这样的SQL操作的处理速度一般非常快,不需要启用并行。

使用并行方式,不论是创建表,还是修改表、创建索引、重建索引,它们的机制都是一样的,那就是Oracle给每个并行服务进程分配一块空间,每个进程在自己的空间里处理数据,最后将处理完毕的数据汇总,完成SQL的操作。

相关参数

和并行相关的参数较多,下面给出几个常见的参数,其它参数请参考官方文档:

CPU_COUNT

参数类型 Integer
默认值为 0
可修改 ALTER SYSTEM
值范围为 0至无限

CPU_COUNT指定了可供Oracle数据库使用的CPU的数量。在核心架构上,它指定了可用的CPU核心的数量。Oracle数据库的各种组件是根据CPU的数量来配置的,例如优化器、并行查询和资源管理器。

如果CPU_COUNT被设置为0(其默认设置),那么Oracle数据库会持续监控操作系统报告的CPU数量,并使用当前的计数。如果CPU_COUNT被设置为0以外的值,那么Oracle数据库将使用这个计数而不是CPU的实际数量,从而禁用动态CPU重新配置。当启用资源管理器时,设置CPU_COUNT将CPU的利用率限制在大约CPU_COUNT处理器。

PARALLEL_THREADS_PER_CPU

参数类型 Integer
默认值 Operating system-dependent, usually 2
可修改性 ALTER SYSTEM
值范围 Any nonzero number

注意:这个参数适用于单实例和RAC环境的并行执行。
PARALLEL_THREADS_PER_CPU确定实例的默认并行度和并行自适应及负载均衡算法。参数描述并行执行期间每个CPU能处理的并行执行进程或线程数。
默认值和平台有关,且在大多数情况下是足够的。当一个具有代表性的并行查询执行,且机器出现过载现象时,那么,你应该减少该参数的值。如果系统是IO限制的,你应该增加该参数。

PARALLEL_MIN_SERVERS

参数类型 Integer
默认值 0
可修改性 ALTER SYSTEM
值范围 0 to value of PARALLEL_MAX_SERVERS
Oracle RAC 多个实例可以有不同的值

注意:该参数使用单实例和RAC环境的并行执行。
PARALLEL_MIN_SERVERS确定实例上并行执行进程的最小数。该值是实例启动时Oracle创建的并行执行进程的数目。

默认值为0,确定实例上并行执行进程的最小数,该值是Oracle实例启动时创建的并行执行进程的数目,可以使用“ ps -ef|grep ora_p0”来查看。Oracle RAC多个实例可以有不同的值。若修改了该值,则只有当数据库实例重启的情况下后台进程数才会变化。

PARALLEL_MAX_SERVERS

默认值为PARALLEL_THREADS_PER_CPU * CPU_COUNT * concurrent_parallel_users * 5。该参数确定一个实例并行执行进程和并行恢复进程的最大数。当需求增加时,Oracle数据库从实例启动时的进程数增加到该参数值。在默认值计算公式中,实例上赋予正在使用的concurrent_parallel_users的值和内存管理设置相关。如果自动内存管理被关闭(手工模式),那么concurrent_parallel_users为1。如果PGA自动内存管理被开启,那么concurrent_parallel_users的值为2.如果除了PGA自动内存管理,全局内存管理或SGA内存目标也被使用,那么,concurrent_parallel_users为4。Oracle RAC多个实例可以有不同值。

如下参考Doc ID 1968840.1

从11gR2开始,有一种新的方法来计算PARALLEL_MAX_SERVERS的默认值。 在11gR2中,PARALLEL_MAX_SERVERS的值以PROCESSES-15为上限。

在12c中,PARALLEL_MAX_SERVERS的值由PROCESSES - N来限定,其中N是一个内部计算的结果,该计算估计了需要为特定数据库保留的最大背景进程的数量。

例如,使用15的值,如11gR2中:

parallel_threads_per_cpu = 2
cpu_count = 4
pga_aggregate_target = 500M
sga_target = 900M
processes = 150

parallel_max_servers = 2 * 4 * 4 * 5 = 160
default value of: parallel_max_servers = min( 150-15 , 160 ) = 135

因此,通过这些值,我们可以得到parallel_max_servers的默认值为135。

注意,如果parallel_max_servers由于进程值的原因而减少,那么你会在警报日志中看到类似以下的情况(例如在实例启动时)。

Mon May 06 18:43:06 2013
Adjusting the default value of parameter parallel_max_servers
from 160 to 135 due to the value of parameter processes (150)
Starting ORACLE instance (normal)

PARALLEL_DEGREE_POLICY

参数类型 String
语法 PARALLEL_DEGREE_POLICY = { MANUAL | LIMITED | AUTO }
默认值 MANUAL
可修改性 ALTER SESSION, ALTER SYSTEM
是否基础 No

注意:该参数尽量不要修改为AUTO,因为相关的Bug较多,一般使用MANUAL即可。

PARALLEL_DEGREE_POLICY确定是否开启自动并行度,语句排队和内存并行执行。
值:
注意:如果一个PARALLEL hint在语句级被使用,无论PARALLEL_DEGREE_POLICY值设置成什么,自动并行度都将被开启。
■ MANUAL
关闭自动并行度,语句排队和内存并行执行。这恢复并行执行到11.2之前的行为。这是默认设置。
■ LIMITED
对某些语句开启自动并行执行,但语句排队和内存并行执行被关闭。自动并行度仅仅适用那些存取显式用PARALELL语句标示默认并行度的表或索引的语句。并不存取这些被显式标示默认并行度的表或索引的语句将保持手工(MANUAL)行为。
■ AUTO
开启自动并行度,语句排队和内存并行执行。

PARALLEL_DEGREE_LIMIT

参数类型 String
语法 PARALLEL_DEGREE_LIMIT = { CPU | IO | integer }
默认值 CPU
可更改性 ALTER SESSION, ALTER SYSTEM
是否基础 No

在并行度自动调整的情况下,Oracle自动决定一个语句是否并行执行和用什么并行度执行。优化器基于语句的资源需求自动决定一个语句的并行度。
然而,为了确保并行服务器进程不会导致系统过载,优化器会限制使用的并行度。这个限制通过PARALLEL_DEGREE_LIMIT来强制实施。
值:
■ CPU
最大并行度被系统CPU数限制。计算限制的公式为PARALLEL_THREADS_PER_CPU *CPU_COUNT * 可用实例数(默认为簇中打开的所有实例,但也能通过PARALLEL_INSTANCE_GROUP或service定义来约束),这是默认的。
■ IO
优化器能用的最大并行度被系统的IO容量限制。系统总吞吐除以每个进程的最大IO带宽计算出。为了使用该IO设置,你必须在系统上运行DBMS_RESOURCE_MANAGER.CALIBRATE_IO过程。该过程将计算系统总吞吐和单个进程的最大IO带宽。
■ integer
当自动并行度被激活时,该参数的数字值确定优化器为一个SQL语句能选择的最大并行度。PARALLEL_DEGREE_POLICY被设置为AUTO或LIMITED时,自动并行度才可以使用。

PARALLEL_FORCE_LOCAL   Rac中有用,减少GC Cache

参数类型 Boolean
默认值 false
可修改性 ALTER SESSION, ALTER SYSTEM
值范围 true | false
是否基础 No
PARALLEL_FORCE_LOCAL控制Oracle RAC环境下的并行执行。默认情况,被选择执行一个SQL语句的并行服务器进程能在簇中任何或所有Oracle RAC节点上操作。通过设置PARALLEL_FORCE_LOCAL为true,并行服务器进程被限制从而都在查询协调器驻留的同一个Oracle RAC节点上操作(语句被执行的节点上) 。

PARALLEL_MIN_PERCENT

参数类型 Integer
默认值 0
可修改性 ALTER SESSION
值范围 0 to 100
Oracle RAC 多个实例能有不同的值

PARALLEL_MIN_PERCENT使得你确定并行执行需要并行执行进程数的最小百分比。设置该参数确保除非有足够的资源可用,否则,不会执行并行操作。默认值0意味着没进程的最小百分比被设置。
考虑以下设置:
PARALLEL_MIN_PERCENT = 50
PARALLEL_MIN_SERVERS = 5
PARALLEL_MAX_SERVERS = 10
如果十个并行执行进程中的8个处于繁忙状态,仅两个进程可用。如果接着你提交一个并行度8的查询,那么,最小50%不能被满足。
你能和PARALLEL_ADAPTIVE_MULTI_USER参数一起使用该参数。在多用户环境,一个单独的用户或应用能设置PARALLEL_MIN_PERCENT为一个有足够的系统资源和可接受的并行度被返回时使用的最小值。

PARALLEL_ADAPTIVE_MULTI_USER    11g搞了好多adaptive

参数类型 Boolean
默认值 true
可修改性 ALTER SYSTEM
取值范围 true | false

被设置为true时,使自适应算法可用,该算法被设计来改善使用并行的多用户环境的性能。
该算法在查询开始时基于负载来自动减少被要求的并行度。实际的并行度基于默认、来自表或hints的并行度,然后除以一个缩减因数。该算法假设系统已经在单用户环境下进行了最优调整。表和hints用默认的并行度。

PARALLEL_MIN_TIME_THRESHOLD

确定一个语句被考虑采用自动并行度前一个语句将用的最小执行时间。默认值为AUTO,表示10s。只有PARALLEL_DEGREE_POLICY被设置为AUTO或LIMITED时,自动并行度才被开启。

MANUAL:关闭自动并行度,语句排队和内存并行执行。这恢复并行执行到11.2之前的行为。这是默认设置。

LIMITED:对某些语句开启自动并行执行,但语句排队和内存并行执行被关闭。自动并行度仅仅适用那些存取显式用PARALELL语句标示默认并行度的表或索引的语句。并不存取这些被显式标示默认并行度的表或索引的语句将保持手工(MANUAL)行为。

AUTO:开启自动并行度,语句排队和内存并行执行。

PARALLEL_SERVERS_TARGET

参数类型 Integer
默认值 PARALLEL_THREADS_PER_CPU * CPU_COUNT * concurrent_parallel_users * 2
可修改性 ALTER SYSTEM
值范围 0 to PARALLEL_MAX_SERVERS
是否基础 No

PARALLEL_SERVERS_TARGET确定语句排队被采用前运行一个语句允许的并行服务器进程数。当参数PARALLEL_DEGREE_POLICY被设置为AUTO,且必需的并行服务器进程不可用时,Oracle将排队要求并行执行的SQL语句。一旦系统上活的并行服务器进程数等于PARALLEL_SERVERS_TARGETS,语句排队将开始。默认地,PARALLEL_SERVERS_TARGETS被设置低于系统上允许的并行服务进程最大数(PARALLEL_MAX_SERVERS),以确保每个并行语句将获得需要的并行服务资源,同时,也避免因为过多的并行服务器进程数而导致系统过载。
一个实例上运行的默认并行度的并发并行用户和内存管理设置相关。如果自动内存管理被关闭(手工模式),那么,并发并行用户数为1.如果PGA自动内存管理被开启,并发并行用户为2。如果除了PGA内存自动管理,还有全局内存管理和SGA内存目标被使用,那么,并发并行用户数为4。
注意即使语句排队被激活,所有串行语句(非并行的)将立即执行。

废弃参数

parallel_automatic_tuning

parallel_server_instances

parallel_io_cap_enabled

parallel_server

并行执行的使用范围

Oracle的并行技术在下面的场景中可以使用:

(1)PARALLEL QUERY(并行查询,简称PQ)。

(2)PARALLEL DDL(并行DDL操作,简称PDDL,例如建表、建索引等)。

(3)PARALLEL DML(并行DML操作,简称PDML,例如INSERT、UPDATE、DELETE等)。

并行查询(PQ)

并行查询可以在查询语句、子查询语句中使用,但是不可以使用在一个远程引用的对象上(例如DBLINK)。当一条SQL语句发生全表扫描、全分区扫描及索引快速全扫描的时候,若优化器满足下面的条件之一就可以使用并行处理:

① 会话级别,会话设置了强制并行,例如,“ALTER SESSION FORCE PARALLEL QUERY PARALLEL 4;”,执行“SELECT COUNT(*) FROM TB_PART_LHR;”,这里的TB_PART_LHR为分区表。

② 语句级别,SQL语句中有Hint提示,例如,使用PARALLEL或者PARALLEL_INDEX。如,“SELECT /*+ PARALLEL(T 4) */ FROM T;”。

③ SQL语句中引用的对象被设置了并行属性。在表和索引的定义中增加并行度属性,该属性可以在创建表和索引时设置,也可对已创建的表和索引的并行度属性进行修改。例如,“ALTER TABLE TB_NAME PARALLEL 4;”、“ALTER TABLE TB_NAME PARALLEL (DEGREE DEFAULT);”。取消表或索引的并行度的SQL为:“ALTER TABLE TB_NAME NOPARALLEL;”。

示例如下:

SYS@orclasm > ALTER TABLE SH.SALES PARALLEL (DEGREE 10);
Table altered.
SYS@orclasm >  SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='SALES' AND OWNER='SH';
DEGREE
--------------------
        10
SYS@orclasm > ALTER TABLE SH.SALES PARALLEL (DEGREE DEFAULT);
Table altered.
SYS@orclasm > SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='SALES' AND OWNER='SH';
DEGREE
-------------------
  DEFAULT
SYS@orclasm >  ALTER TABLE  SH.SALES NOPARALLEL;
Table altered.
SYS@orclasm > SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='SALES' AND OWNER='SH';
DEGREE
-------------------
         1
SYS@orclasm > CREATE TABLE SCOTT.AA AS SELECT * FROM DUAL;
Table created.
SYS@orclasm >  SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='AA' AND OWNER='SCOTT';
DEGREE
--------------------
         1

在日常使用上,一般不建议在对象级别定义并行度,因为这会导致相关对象的操作都变为并行处理,而并行处理会占用大量的CPU资源,导致数据库整体性能失控。一般在会话或语句级别进行处理。

并行DDL操作(PDDL)

表或索引的CREATE或ALTER操作可以使用并行。例如,以下表操作可以使用并行执行:

建表:CREATE TABLE … AS SELECT(CTAS)
表移动:ALTER TABLE … MOVE
表分区移动:ALTER TABLE … MOVE PARTITION
表分区并行分解:ALTER TABLE … SPLIT PARTITION
表分区并行合并:ALTER TABLE … COALESCE PARTITION
创建和校验约束:ALTER TABLE … ADD CONSTRAINT
创建索引:CREATE INDEX
重建索引:ALTER INDEX … REBULD
重建索引分区:ALTER INDEX … REBULD PARTITION
索引分区的分解:ALTER INDEX … SPLIT PARTITION

并行DML操作(PDML)

Oracle可以对DML操作使用并行执行。如果要让DML操作使用并行执行,那么必须显式地在会话里执行如下命令

ALTER SESSION ENABLE PARALLEL DML;

只有执行了这个命令,Oracle才会对之后符合并行条件的DML操作并行执行,如果没有这个设定,那么即使SQL中指定了并行执行,Oracle也会忽略它。

以下给出一个并行UPDATE的示例:

LHR@TEST> CREATE TABLE TB_LHR20160518 AS  SELECT * FROM DBA_OBJECTS;
Table created.
LHR@TEST> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL,NULL,'BASIC +PARALLEL'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
Plan hash value: 2194116729
-----------------------------------------------------------------------------
| Id  | Operation             | Name           |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------
|   0 | UPDATE STATEMENT      |                |        |      |            |
|   1 |  UPDATE               | TB_LHR20160518 |        |      |            |
|   2 |   PX COORDINATOR      |                |        |      |            |
|   3 |    PX SEND QC (RANDOM)| :TQ10000       |  Q1,00 | P->S | QC (RAND)  |
|   4 |     PX BLOCK ITERATOR |                |  Q1,00 | PCWC |            |
|   5 |      TABLE ACCESS FULL| TB_LHR20160518 |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------------
12 rows selected.
LHR@TEST> EXPLAIN PLAN FOR UPDATE /*+ PARALLEL (T1,4) */ TB_LHR20160518 T1 SET OBJECT_NAME='LHR';
Explained.
LHR@TEST> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL,NULL,'BASIC +PARALLEL'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2194116729
-----------------------------------------------------------------------------
| Id  | Operation             | Name           |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------
|   0 | UPDATE STATEMENT      |                |        |      |            |
|   1 |  UPDATE               | TB_LHR20160518 |        |      |            |
|   2 |   PX COORDINATOR      |                |        |      |            |
|   3 |    PX SEND QC (RANDOM)| :TQ10000       |  Q1,00 | P->S | QC (RAND)  |
|   4 |     PX BLOCK ITERATOR |                |  Q1,00 | PCWC |            |
|   5 |      TABLE ACCESS FULL| TB_LHR20160518 |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------------
12 rows selected.
LHR@test> ALTER SESSION ENABLE  PARALLEL DML;
Session altered.
LHR@TEST> EXPLAIN PLAN FOR UPDATE /*+ PARALLEL (T1,4) */ TB_LHR20160518 T1 SET OBJECT_NAME='LHR';
Explained.
LHR@TEST> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL,NULL,'BASIC +PARALLEL'));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
Plan hash value: 3729706116
-----------------------------------------------------------------------------
| Id  | Operation             | Name           |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------
|   0 | UPDATE STATEMENT      |                |        |      |            |
|   1 |  PX COORDINATOR       |                |        |      |            |
|   2 |   PX SEND QC (RANDOM) | :TQ10000       |  Q1,00 | P->S | QC (RAND)  |
|   3 |    UPDATE             | TB_LHR20160518 |  Q1,00 | PCWP |            |
|   4 |     PX BLOCK ITERATOR |                |  Q1,00 | PCWC |            |
|   5 |      TABLE ACCESS FULL| TB_LHR20160518 |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------------
12 rows selected.

通过执行计划可以看出,只有执行了“ALTER SESSION ENABLE PARALLEL DML;”后,UPDATE操作才真正地实现了并行操作,如果不执行该语句,那么只是执行了并发查询,并没有实现并发更新操作。

下表列出了这3种并行处理方式的开启及禁用语句:

类别区别
并行查询(PQ)默认开启
查询SELECT D.PQ_STATUS FROM V$SESSION D WHERE D.SID=USERENV('sid');
启用、禁用ALTER SESSION ENABLE PARALLEL QUERY;--启用
ALTER SESSION FORCE PARALLEL QUERY PARALLEL n; --强制开启
ALTER SESSION DISABLE PARALLEL QUERY; --禁用
并行DDL(PDDL)默认开启
查询SELECT D.PDDL_STATUS FROM V$SESSION D WHERE D.SID=USERENV('sid');
启用、禁用ALTER SESSION ENABLE PARALLEL DDL; --启用
ALTER SESSION FORCE PARALLEL DDL PARALLEL n; --强制开启
ALTER SESSION DISABLE PARALLEL DDL; --禁用
并行DML(PDML)默认关闭
查询SELECT D.PDML_STATUS FROM V$SESSION D WHERE D.SID=USERENV('sid');
启用、禁用ALTER SESSION ENABLE PARALLEL DML; --启用
ALTER SESSION FORCE PARALLEL DML PARALLEL n; --强制开启
ALTER SESSION DISABLE PARALLEL DML; --禁用

RAC中的并行

如果连接Oracle RAC数据库,那么一个节点上的并发操作可以分布到多个节点上同时执行。可以使用视图GV$PX_SESSION查询并行会话的进程

这是一个Oracle 11g的RAC环境,下面建立一张测试表,建立过程中设置表的并行度:

[ZFWWLHRDB1:oracle]:/oracle>ORACLE_SID=raclhr1
[ZFWWLHRDB1:oracle]:/oracle>sqlplus / as sysdba
SQL*Plus: Release 11.2.0.4.0 Production on Fri Sep 30 14:52:23 2016
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
SYS@raclhr1> show parameter cluster
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cluster_database                     boolean     TRUE
cluster_database_instances           integer     2
cluster_interconnects                string
SYS@raclhr1> CREATE TABLE T_PARALLEL_LHR NOLOGGING PARALLEL 4
  2   AS SELECT A.* FROM DBA_OBJECTS A, DBA_TABLES
  3   WHERE ROWNUM <= 5000000;
Table created.
SYS@raclhr1> SELECT * FROM V$MYSTAT WHERE ROWNUM<=1;
       SID STATISTIC#      VALUE
---------- ---------- ----------
       167          0          0
SYS@raclhr1> set autot on
SYS@raclhr1> SET LINESIZE 9999
SYS@raclhr1> SET PAGESIZE 9999
SYS@raclhr1> SELECT COUNT(*) FROM T_PARALLEL_LHR a,T_PARALLEL_LHR b where rownum<=1000000;
  COUNT(*)
----------
   1000000
Execution Plan
----------------------------------------------------------
Plan hash value: 1691788013
-------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name           | Rows  | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                |     1 |  2057M  (5)|999:59:59 |        |      |            |
|   1 |  SORT AGGREGATE             |                |     1 |            |          |        |      |            |
|*  2 |   COUNT STOPKEY             |                |       |            |          |        |      |            |
|   3 |    PX COORDINATOR           |                |       |            |          |        |      |            |
|   4 |     PX SEND QC (RANDOM)     | :TQ10001       |    23T|  2057M  (5)|999:59:59 |  Q1,01 | P->S | QC (RAND)  |
|*  5 |      COUNT STOPKEY          |                |       |            |          |  Q1,01 | PCWC |            |
|   6 |       MERGE JOIN CARTESIAN  |                |    23T|  2057M  (5)|999:59:59 |  Q1,01 | PCWP |            |
|   7 |        PX BLOCK ITERATOR    |                |  4857K|  5396   (1)| 00:01:05 |  Q1,01 | PCWC |            |
|   8 |         TABLE ACCESS FULL   | T_PARALLEL_LHR |  4857K|  5396   (1)| 00:01:05 |  Q1,01 | PCWP |            |
|   9 |        BUFFER SORT          |                |  4857K|  2057M  (5)|999:59:59 |  Q1,01 | PCWP |            |
|  10 |         PX RECEIVE          |                |  4857K|  5396   (1)| 00:01:05 |  Q1,01 | PCWP |            |
|  11 |          PX SEND BROADCAST  | :TQ10000       |  4857K|  5396   (1)| 00:01:05 |  Q1,00 | P->P | BROADCAST  |
|  12 |           PX BLOCK ITERATOR |                |  4857K|  5396   (1)| 00:01:05 |  Q1,00 | PCWC |            |
|  13 |            TABLE ACCESS FULL| T_PARALLEL_LHR |  4857K|  5396   (1)| 00:01:05 |  Q1,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(ROWNUM<=1000000)
   5 - filter(ROWNUM<=1000000)
Note
-----
   - dynamic sampling used for this statement (level=4)
Statistics
----------------------------------------------------------
        112  recursive calls
          8  db block gets
      72078  consistent gets
      74257  physical reads
          0  redo size
        526  bytes sent via SQL*Net to client
        520  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          4  sorts (disk)
          1  rows processed

从执行计划可以看到,Oracle选择了并行执行。

新建立一个会话,在执行上面这个并行查询的同时查询GV$PX_SESSION(或GV$PX_PROCESS)视图:

SYS@raclhr1> SELECT * FROM GV$PX_SESSION WHERE QCSID=167;
   INST_ID SADDR                   SID    SERIAL#      QCSID  QCSERIAL#  QCINST_ID SERVER_GROUP SERVER_SET    SERVER#     DEGREE REQ_DEGREE
---------- ---------------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ----------
         1 07000100538364A0        199         35        167          5          1            1          1          1          4          4
         1 0700010053894FC0        230         35        167          5          1            1          1          2          4          4
         1 0700010053607480         10         37        167          5          1            1          2          1          4          4
         1 070001005366F240         38          3        167          5          1            1          2          2          4          4
         1 07000100537DAA60        167          5        167
         2 070001005383F740        196         43        167          5          1            1          1          3          4          4
         2 07000100536D3F20         67          9        167          5          1            1          1          4          4          4
         2 07000100536168E0          5          5        167          5          1            1          2          3          4          4
         2 07000100536784E0         35        113        167          5          1            1          2          4          4          4
9 rows selected.

很显然,并行查询的4个进程已经分布到两个节点上同时执行了,每个节点上创建4个并行从属进程。

案例解析

背景

客户在使用parallel 10后,数据库未按照指定的并行度10,生成进程,RAC双节点生产大概300多个进程,相关主SQL如下。

分析

上述SQL语法问题

官方对于这个parallel的hint定义如下:

For a statement-level PARALLEL hint:

  • PARALLEL: The statement always is run parallel, and the database computes the degree of parallelism, which can be 2 or greater.
  • PARALLEL (DEFAULT): The optimizer calculates a degree of parallelism equal to the number of CPUs available on all participating instances times the value of the PARALLEL_THREADS_PER_CPU initialization parameter.
  • PARALLEL (AUTO): The database computes the degree of parallelism, which can be 1 or greater. If the computed degree of parallelism is 1, then the statement runs serially.
  • PARALLEL (MANUAL): The optimizer is forced to use the parallel settings of the objects in the statement.
  • PARALLEL (integer): The optimizer uses the degree of parallelism specified by integer.
    In the following example, the optimizer calculates the degree of parallelism. The statement always runs in parallel.
SELECT /*+ PARALLEL */ last_name
  FROM employees;

In the following example, the optimizer calculates the degree of parallelism, but that degree may be 1, in which case the statement will run serially.

SELECT /*+ PARALLEL (AUTO) */ last_name
  FROM employees;

In the following example, the PARALLEL hint advises the optimizer to use the degree of parallelism currently in effect for the table itself, which is 5:

CREATE TABLE parallel_table (col1 number, col2 VARCHAR2(10)) PARALLEL 5; 

SELECT /*+ PARALLEL (MANUAL) */ col2
  FROM parallel_table;

上述代码通过 select /*+ parallel 10*/,目的是想实现开10个并行进行查询,正确写法为select /*+ parallel (10)*/,由于语法错误,数据库识别到的可能为select /*+ parallel */,这样并行是开了,但是有系统自己决定并行度,本案例为RAC,节点并行度为 PARALLEL_THREADS_PER_CPU *CPU_COUNT * 可用实例数。

正确写法

相关视图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值