深入理解Oracle 的并行执行.docx

上传人:b****2 文档编号:3182868 上传时间:2023-05-05 格式:DOCX 页数:79 大小:825.96KB
下载 相关 举报
深入理解Oracle 的并行执行.docx_第1页
第1页 / 共79页
深入理解Oracle 的并行执行.docx_第2页
第2页 / 共79页
深入理解Oracle 的并行执行.docx_第3页
第3页 / 共79页
深入理解Oracle 的并行执行.docx_第4页
第4页 / 共79页
深入理解Oracle 的并行执行.docx_第5页
第5页 / 共79页
深入理解Oracle 的并行执行.docx_第6页
第6页 / 共79页
深入理解Oracle 的并行执行.docx_第7页
第7页 / 共79页
深入理解Oracle 的并行执行.docx_第8页
第8页 / 共79页
深入理解Oracle 的并行执行.docx_第9页
第9页 / 共79页
深入理解Oracle 的并行执行.docx_第10页
第10页 / 共79页
深入理解Oracle 的并行执行.docx_第11页
第11页 / 共79页
深入理解Oracle 的并行执行.docx_第12页
第12页 / 共79页
深入理解Oracle 的并行执行.docx_第13页
第13页 / 共79页
深入理解Oracle 的并行执行.docx_第14页
第14页 / 共79页
深入理解Oracle 的并行执行.docx_第15页
第15页 / 共79页
深入理解Oracle 的并行执行.docx_第16页
第16页 / 共79页
深入理解Oracle 的并行执行.docx_第17页
第17页 / 共79页
深入理解Oracle 的并行执行.docx_第18页
第18页 / 共79页
深入理解Oracle 的并行执行.docx_第19页
第19页 / 共79页
深入理解Oracle 的并行执行.docx_第20页
第20页 / 共79页
亲,该文档总共79页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

深入理解Oracle 的并行执行.docx

《深入理解Oracle 的并行执行.docx》由会员分享,可在线阅读,更多相关《深入理解Oracle 的并行执行.docx(79页珍藏版)》请在冰点文库上搜索。

深入理解Oracle 的并行执行.docx

深入理解Oracle的并行执行

深入理解Oracle的并行执行

摘要:

Oracle并行执行是一种分而治之的方法。

执行一个sql时,分配多个并行进程同时执行数据扫描,连接以及聚合等操作,使用更多的资源,得到更快的sql响应时间。

并行执行是充分利用硬件资源,处理大量数据时的核心技术。

Oracle并行执行是一种分而治之的方法。

执行一个sql时,分配多个并行进程同时执行数据扫描,连接以及聚合等操作,使用更多的资源,得到更快的sql响应时间。

并行执行是充分利用硬件资源,处理大量数据时的核心技术。

在本文中,在一个简单的星型模型上,我会使用大量例子和sqlmonitor报告,力求以最直观简单的方式,向读者阐述并行执行的核心内容:

•Oracle并行执行为什么使用生产者——消费者模型。

•如何阅读并行执行计划。

•不同的数据分发方式分别适合什么样的场景。

•使用partitionwisejoin和并行执行的组合提高性能。

•数据倾斜会对不同的分发方式带来什么影响。

•由于生产者-‐消费者模型的限制,执行计划中可能出现阻塞点。

•布隆过滤是如何提高并行执行性能的。

•现实世界中,使用并行执行时最常见的问题。

术语说明:

S:

时间单位秒。

K:

数量单位一千。

M:

 数量单位一百万, 或者时间单位分钟。

DoP:

DegreeofParallelism,并行执行的并行度。

QC:

并行查询的QueryCoordinator。

PX进程:

ParallelExecutionSlaves。

AAS:

Averageactivesession,并行执行时平均的活动会话数。

分发:

pqdistributionmethod,并行执行的分发方式,包括replicate,broadcast,hash和adaptive分发等4种方式,其中adaptive分发是12c引入的的新特性,我将在本篇文章中一一阐述。

Hashjoin的左边:

驱动表,thebuildsideofhashjoin,一般为小表。

Hashjoin的右边:

被驱动表,theprobesideofhashjoin,一般为大表。

布隆过滤:

bloomfilter,一种内存数据结构,用于判断一个元素是否属于一个集合。

测试环境和数据

Oracle版本为12.1.0.2.2,两个节点的RAC,硬件为ExadataX3-‐8。

这是一个典型的星型模型,事实表lineorder有3亿行记录,维度表part/customer分别包含1.2M

和1.5M行记录,3个表都没有进行分区,lineorder大小接近30GB。

[js]viewplaincopyprint?

select  

owner seg_owner,  

segment_name seg_segment_name, round(bytes/1048576,2) SEG_MB  

from  

   

dba_segments where  

owner = 'SID'  

and segment_name in ('LINEORDER','PART','CUSTOMER')  

/  

  

OWNER   SEGMENT_NAME SEGMENT_TYPE   SEG_MB  

------ ------------ ------------ -------- SID   LINEORDER   TABLE   30407.75  

SID CUSTOMER    TABLE   168  

SID PART    TABLE   120  

select

ownerseg_owner,

segment_nameseg_segment_name,round(bytes/1048576,2)SEG_MB

from

dba_segmentswhere

owner='SID'

andsegment_namein('LINEORDER','PART','CUSTOMER')

/

OWNERSEGMENT_NAMESEGMENT_TYPESEG_MB

--------------------------------------SIDLINEORDERTABLE30407.75

SIDCUSTOMERTABLE168

SIDPARTTABLE120

本篇文章所有的测试,除非特别的说明,我关闭了12c的adaptiveplan特性,参数optimizer_adaptive_features被默认设置为false。

Adaptive相关的特性如cardinalityfeedback,adaptivedistributionmethod,adaptivejoin都不会启用。

如果检查执行计划的outline数据,你会发现7个优化器相关的隐含参数被设置为关闭状态。

事实上,12c优化器因为引入adaptiveplan特性,比以往版本复杂得多,剖析12c的优化器的各种新特性,我觉得非常具有挑战性,或许我会在另一篇文章里尝试一下。

[js]viewplaincopyprint?

select * from table(dbms_xplan.display_cursor('77457qc9a324k',0,’outline’));  

...  

Outline Data  

-------------  

/*+ 

BEGIN_OUTLINE_DATA 

IGNORE_OPTIM_EMBEDDED_HINTS 

OPTIMIZER_FEATURES_ENABLE('12.1.0.2') 

DB_VERSION('12.1.0.2') 

OPT_PARAM('_optimizer_use_feedback' 'false') 

OPT_PARAM('_px_adaptive_dist_method' 'off') 

OPT_PARAM('_optimizer_dsdir_usage_control' 0) 

OPT_PARAM('_optimizer_adaptive_plans' 'false') 

OPT_PARAM('_optimizer_strans_adaptive_pruning' 'false') 

OPT_PARAM('_optimizer_gather_feedback' 'false') 

OPT_PARAM('_optimizer_nlj_hj_adaptive_join' 'false') 

OPT_PARAM('optimizer_dynamic_sampling' 11) 

ALL_ROWS 

…… 

END_OUTLINE_DATA 

*/  

select*fromtable(dbms_xplan.display_cursor('77457qc9a324k',0,’outline’));

...

OutlineData

-------------

/*+

BEGIN_OUTLINE_DATA

IGNORE_OPTIM_EMBEDDED_HINTS

OPTIMIZER_FEATURES_ENABLE('12.1.0.2')

DB_VERSION('12.1.0.2')

OPT_PARAM('_optimizer_use_feedback''false')

OPT_PARAM('_px_adaptive_dist_method''off')

OPT_PARAM('_optimizer_dsdir_usage_control'0)

OPT_PARAM('_optimizer_adaptive_plans''false')

OPT_PARAM('_optimizer_strans_adaptive_pruning''false')

OPT_PARAM('_optimizer_gather_feedback''false')

OPT_PARAM('_optimizer_nlj_hj_adaptive_join''false')

OPT_PARAM('optimizer_dynamic_sampling'11)

ALL_ROWS

……

END_OUTLINE_DATA

*/

并行初体验

串行执行

以下sql对customers和lineorder连接之后,计算所有订单的全部利润。

串行执行时不使用parallelhint:

[js]viewplaincopyprint?

select /*+ monitor */  

sum(lo_revenue)  

from  

lineorder, customer  

where  

lo_custkey = c_custkey;  

select/*+monitor*/

sum(lo_revenue)

from

lineorder,customer

where

lo_custkey=c_custkey;

串行执行时,sql执行时间为1.5分钟,dbtime为1.5分钟。

执行计划有5行,一个用户进程工作完成了对customer,lineorder两个表的扫描,hashjoin,聚合以及返回数据的所有操作。

此时AAS(averageactivesessions)为1,sql执行时间等于dbtime。

几乎所有的dbtime都为dbcpu,72%的cpu花在了第二行的hashjoin操作。

因为测试机器为一台ExadataX3——8,30GB的IO请求在一秒之内处理完成。

CelloffloadEfficiency等于87%意味着经过存储节点扫描,过滤不需要的列,最终返回计算节点的数据大小只有30GB的13%。

并行执行

使用hintparallel(4),指定DoP=4并行执行同样的sql:

[js]viewplaincopyprint?

select /*+ monitor parallel(4)*/  

sum(lo_revenue)  

from  

lineorder, customer  

where  

lo_custkey = c_custkey;  

select/*+monitorparallel(4)*/

sum(lo_revenue)

from

lineorder,customer

where

lo_custkey=c_custkey;

SQL执行时间为21s,dbtime为1.4分钟。

DoP=4,在两个实例上执行。

执行计划从5行增加为9行,从下往上分别多了’PXBLOCKITERATOR’,‘SORTAGGREGATE’,‘PXSENDQC(RANDOM)’和’PXCOORDINATOR’这四个操作。

其中3到8行的操作为并行处理,sql的执行顺序为:

每个PX进程扫描维度表customer(第6行),以数据块地址区间作为单位(第7行)扫描四分之一的事实表lineorder(第8行),接着进行hashjoin(第5行),然后对连接之后的数据做预先聚合(第4行),最后把结果给QC(第三行)。

QC接收数据(第2行)之后,做进一步的汇总(第1行),最后返回数据(第0行)。

SQL执行时间比原来快了4倍,因为最消耗时间的操作,比如对lineorder的全表扫描,hashjoin和聚合,我们使用4个进程并行处理,因此最终sql执行时间为串行执行的1/4。

另一方面,dbtime并没有明显下降,并行时1.4m,串行时为1.5m,从系统的角度看,两次执行消耗的系统资源是一样的。

        

DoP=4时,因为没有涉及数据的分发(distribution),QC只需分配一组PX进程,四个PX进程分别为实例1和2的p000/p0001。

我们可以从系统上查看这4个PX进程。

每个PX进程消耗大致一样的dbtime,CPU和IO资源。

AAS=4,这是最理想的情况,每个PX进程完成同样的工作量,一直保持活跃。

没有串行点,没有并行执行倾斜。

AAS=4,查看活动信息时,为了更好的展示活动信息,注意点掉”CPUCores”这个复选框。

在Linux系统上显示这四个PX进程。

[js]viewplaincopyprint?

[oracle@exa01db01 sidney]$ ps -ef | egrep "p00[01]_SSB"  

oracle 20888 1 4 2014 ?

 18:

50:

59 ora_p000_SSB1  

oracle 20892 1 4 2014 ?

 19:

01:

29 ora_p001_SSB1  

[oracle@exa01db01 sidney]$ ssh exa01db02 'ps -ef | egrep "p00[01]_SSB"'  

oracle 56910 1 4 2014 ?

 19:

01:

03 ora_p000_SSB2  

oracle 56912 1 4 2014 ?

 18:

53:

30 ora_p001_SSB2  

[oracle@exa01db01sidney]$ps-ef|egrep"p00[01]_SSB"

oracle20888142014?

18:

50:

59ora_p000_SSB1

oracle20892142014?

19:

01:

29ora_p001_SSB1

[oracle@exa01db01sidney]$sshexa01db02'ps-ef|egrep"p00[01]_SSB"'

oracle56910142014?

19:

01:

03ora_p000_SSB2

oracle56912142014?

18:

53:

30ora_p001_SSB2

小结

本节的例子中,DoP=4,并行执行时分配了4个PX进程,带来4倍的性能提升。

SQLmonitor报告包含了并行执行的总体信息和各种细节,比如QC,DoP,并行执行所在的实例,每个PX进程消耗的资源,以及执行SQL时AAS。

生产者-消费者模型

在上面并行执行的例子中,每个px进程都会扫描一遍维度表customer,然后扫描事实表lineorder进行hashjoin。

这时没有数据需要进行分发,只需要分配一组px进程。

这种replicate维度表的行为,是12c的新特性,由参数_px_replication_enabled控制。

更常见情况是并行执行时,QC需要分配两组PX进程,互为生产者和消费者协同工作,完成并行执行计划。

架构图1如下:

       

Broadcast分发,一次数据分发

为了举例说明两组px进程如何协作的,设置_px_replication_enabled为false。

QC会分配两组PX进程,一组为生产者,一组为消费者。

见下图,此时sql执行时间为23s,执行时间变慢了2s,dbtime仍为1.5分钟。

       

最大的变化来自执行计划,现在执行计划有12行。

增加了对customer的并行扫描PXBLOCKITERATOR(第8行),分发’PXSENDBROADCAST’和接收’PXRECEIVE’。

执行计划中出现了两组PX进程,除了之前蓝色的多人标志,现在出现了红色的多人标志。

此时,SQL的执行顺序为:

4个红色的PX进程扮演生产者角色,扫描维度表customer,把数据通过broadcast的方式分发给每一个扮演消费者的蓝色PX进程。

因为DoP=4,每一条被扫描出来的记录被复制了4份,从sqlmonitor的第9行,customer全表扫描返回1。

5m行数据,第8行的分发和第7行的接受之时,变成了6m行记录,每个作为消费者的蓝色px进程都持有了一份完整包含所有custome记录的数据,并准备好第5行hashjoin的buildtable。

4个作为消费者的蓝色PX进程,以数据块地址区间为单位扫描事实表lineorder(第10/11行);同时和已经持有的customer表的数据进hashjoin(第5行),然后对满足join条件的数据做预聚合(第4行),因为我们查询的目标是对所有lo_revenue求和,聚合之后每个PX进程只需输出一个总数。

4个蓝色的PX进程反过来作为生产者,把聚合的数据发给消费者QC(第3行和第2行)。

由QC对接收到4行记录做最后的聚合,然后返回给用户。

使用broadcast的分发方式,只需要把customer的数据广播给每个消费者。

Lineorder的数不需要重新分发。

因为lineorder的数据量比customer大的多,应该避免对lineorder的数据进行分发,这种执行计划非常适合星型模型的数据。

        

观察sqlmonitor报告中Parallel标签下的信息,红色的PX进程为实例1、2上的p002/p003进程,蓝色的PX进程为p000/p001进程,因为蓝色的PX进程负责扫描事实表lineorder,hashjoin和聚合,所以消耗几乎所有的dbtime。

 

        

生产者-消费者模型工作原理

并行查询之后,可以通过视图V$PQ_TQSTAT,验证以上描述的执行过程。

实例1、2上的p002/p003进程作为生产者,几乎平均扫描customer的1/4记录,把每一条记录广播给4个消费者PX进程,发送的记录数之和为6m行。

通过tablequeue0(TQ_ID=0),每个作为消费者的p000/p001进程,接收了完整的1。

5m行customer记录,接收的记录数之和为6m行。

实例1、2上的p000/p0001进程作为生产者,通过tablequeue1(TQ_ID=1),把聚合的一条结果记录发给作为消费者的QC。

QC作为消费者,接收了4行记录。

[js]viewplaincopyprint?

SELECT  

dfo_number, tq_id, server_type, instance, process, num_rows  

FROM  

V$PQ_TQSTAT  

ORDER BY  

dfo_number DESC, tq_id, server_type desc, instance, process;  

DFO_NUMBER TQ_ID SERVER_TYPE INSTANCE PROCESS NUM_ROWS  

---------- ---------- -------------- ---------- --------- ----------  

1 0 Producer 1 P002 1461932  

1 0 Producer 1 P003 1501892  

1 0 Producer 2 P002 1575712  

1 0 Producer 2 P003 1460464  

1 0 Consumer 1 P000 1500000  

1 0 Consumer 1 P001 1500000  

1 0 Consumer 2 P000 1500000  

1 0 Consumer 2 P001 1500000  

1 1 Producer 1 P000 1  

1 1 Producer 1 P001 1  

1 1 Producer 2 P000 1  

1 1 Producer 2 P001 1  

1 1 Consumer 1 QC 4  

13 rows selected.  

SELECT

dfo_number,tq_id,server_type,instance,process,num_rows

FROM

V$PQ_TQSTAT

ORDERBY

dfo_numberDESC,tq_id,server_typedesc,instance,process;

DFO_NUMBERTQ_IDSERVER_TYPEINSTANCEPROCESSNUM_ROWS

---------------------------------------------------------------

10Producer1P0021461932

10Producer1P0031501892

10Producer2P0021575712

10Producer2P0031460464

10Consumer1P0001500000

10Consumer1P0011500000

10Consumer2P0001500000

10Consumer2P0011500000

11Producer1P0001

11Producer1P0011

11Producer2P0001

11Producer2P0011

11Consumer1QC4

13rowsselected.

那么,以上的输出中,DFO_NUMBER和TQ_ID这两列表示什么意思呢?

DFO代表DataFlowOperator,是执行计划中可以并行执行的操作。

一个QC代表一棵DFO树(tree),包含多个DFO;同一个QC中所有并行操作的DFO_NUMBER是相同的,此例中,所有DFO_NUMBER为1。

执行计划包含多个QC的例子也不少见,比如使用unionall的语句,unionall每个分支都是独立的DFO树,不同的DFO树之间可以并行执行。

本篇文章仅讨论执行计划只有一个QC的情况。

TQ代表tablequeue,用以PX进程之间或者和QC通信连接。

以上执行计划中,tablequeue0为PX进程之间的连接,tablequeue1为PX进程和QC之间的连接。

生产者通过tablequeue分发数据,消费者从tablequeue接收数据。

不同的tablequeue编号,代表了不同的数据分发。

通过tablequeue,我们可以理解Oracle并行执行使用生产者-‐消费者模型的本质:

同一棵DFO树中,最多只有两组PX进程。

每个生产者进程都存在一个和每个消费者进程的连接,每个PX进程和QC都存在一个连接。

假设DoP=n,连接总数为(n*n+2*n),随着n的增长,连接总数会爆炸型增长。

Oracle并行执行设计时,采用生产者和消费者模型,考虑到连接数的复杂度,每个DFO最多只分配两组PX进程。

假设DoP=100时,两组PX进程之间的连接总数为10000。

假设可以分配三组PX进程一起完成并行执行计划,那么三组PX之间连接总数会等于1百万,维护这么多连接,是一个不可能的任务。

同一棵DFO树中,两组PX进程之间,同一时间只存在一个活跃的数据分发。

如果执行路径很长,数据需要多次分发,两组PX进程会变换生产者消费者角色,相互协作,完成所有并行操作。

每次数据分发,对应的tablequeue的编号不同。

一个活跃的数据分发过程,需要两组PX进程都参与,一组为生产者发送数据,一组为消费者接收数据。

因为一个DFO里最多只有两组PX进程,意味着,PX进程之间,同一时间只能有一

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2