您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
陈焕生:深入理解Oracle 的并行执行(一)
 
作者 陈焕生 火龙果软件  发布于 2015-3-2
  2184  次浏览      35
 

Oracle并行执行是一种分而治之的方法。执行一个sql 时,分配多个并行进程同时执行数据扫描,连接以及聚合等操作,使用更多的资源,得到更快的sql 响应时间。并行执行是充分利用硬件资源,处理大量数据时的核心技术。 

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

• Oracle 并行执行为什么使用生产者——消费者模型。 
• 如何阅读并行执行计划。 
• 不同的数据分发方式分别适合什么样的场景。 
• 使用partition wise join 和并行执行的组合提高性能。 
• 数据倾斜会对不同的分发方式带来什么影响。 
• 由于生产者-­‐消费者模型的限制,执行计划中可能出现阻塞点。 
• 布隆过滤是如何提高并行执行性能的。 
• 现实世界中,使用并行执行时最常见的问题。

术语说明:

  1. S: 时间单位秒。
  2. K: 数量单位一千。
  3. M:  数量单位一百万,  或者时间单位分钟。
  4. DoP: Degree of Parallelism, 并行执行的并行度。
  5. QC: 并行查询的 Query Coordinator。
  6. PX 进程: Parallel Execution Slaves。
  7. AAS: Average active session, 并行执行时平均的活动会话数。
  8. 分发: pq distribution method, 并行执行的分发方式, 包括 replicate, broadcast, hash 和 adaptive分发等 4 种方式, 其中 adaptive 分发是 12c 引入的的新特性, 我将在本篇文章中一一阐述。
  9. Hash join 的左边: 驱动表, the build side of hash join, 一般为小表。
  10. Hash join 的右边: 被驱动表, the probe side of hash join, 一般为大表。
  11. 布隆过滤: bloom filter, 一种内存数据结构, 用于判断一个元素是否属于一个集合。

测试环境和数据

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

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

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

本篇文章所有的测试,除非特别的说明,我关闭了12c的adaptive plan特性,参数optimizer_adaptive_features被默认设置为false。Adaptive相关的特性如cardinality feedback,adaptive distribution method,adaptive join都不会启用。如果检查执行计划的outline数据,你会发现7个优化器相关的隐含参数被设置为关闭状态。事实上,12c优化器因为引入adaptive plan特性,比以往版本复杂得多,剖析12c的优化器的各种新特性,我觉得非常具有挑战性,或许我会在另一篇文章里尝试一下。 

并行初体验

串行执行

以下sql对customers和lineorder连接之后,计算所有订单的全部利润。 串行执行时不使用parallel hint:

串行执行时,sql执行时间为1.5分钟,dbtime为1.5分钟。执行计划有5行,一个用户进程工作完成了对customer,lineorder两个表的扫描,hashjoin,聚合以及返回数据的所有操作。此时AAS(average active sessions)为1,sql执行时间等于db time。几乎所有的dbtime都为db cpu,72%的cpu花在了第二行的hash join操作。因为测试机器为一台Exadata X3——8,30GB的IO请求在一秒之内处理完成。Celloffload Efficiency等于87%意味着经过存储节点扫描,过滤不需要的列,最终返回计算节点的数据大小只有30GB的13%。

并行执行

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

SQL执行时间为21s,db time为1.4分钟。DoP=4,在两个实例上执行。执行计划从5行增加为9行,从下往上分别多了’PXBLOCKITERATOR’, ‘SORTAGGREGATE’, ‘PXSENDQC(RANDOM)’ 和 ’PXCOORDINATOR’ 这四个操作。

其中3到8行的操作为并行处理,sql的执行顺序为:每个PX进程扫描维度表customer(第6行),以数据块地址区间作为单位(第7行)扫描四分之一的事实表lineorder(第8行),接着进行hash join(第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进程消耗大致一样的db time,CPU和IO资源。AAS=4,这是最理想的情况,每个PX进程完成同样的工作量,一直保持活跃。没有串行点,没有并行执行倾斜。

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

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

小结

本节的例子中,DoP=4,并行执行时分配了4个PX进程,带来4倍的性能提升。SQL monitor报告包含了并行执行的总体信息和各种细节,比如QC,DoP,并行执行所在的实例,每个PX进程消耗的资源,以及执行SQL时AAS。

生产者-消费者模型

在上面并行执行的例子中,每个px进程都会扫描一遍维度表customer,然后扫描事实表lineorder进行hash join。这时没有数据需要进行分发,只需要分配一组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的执行顺序为:

  1. 4个红色的PX进程扮演生产者角色,扫描维度表customer,把数据通过broadcast的方式分发给每一个扮演消费者的蓝色PX进程。因为DoP=4,每一条被扫描出来的记录被复制了4份,从sqlmonitor的第9行,customer全表扫描返回1。5m行数据,第8行的分发和第7行的接受之时,变成了6m行记录,每个作为消费者的蓝色px进程都持有了一份完整包含所有custome记录的数据,并准备好第5行hashjoin的buildtable。
  2. 4个作为消费者的蓝色PX进程,以数据块地址区间为单位扫描事实表lineorder(第10/11行);同时和已经持有的customer表的数据进hashjoin(第5行),然后对满足join条件的数据做预聚合(第4行),因为我们查询的目标是对所有lo_revenue求和,聚合之后每个PX进程只需输出一个总数。
  3. 4个蓝色的PX进程反过来作为生产者,把聚合的数据发给消费者QC(第3行和第2行)。由QC对接收到4行记录做最后的聚合,然后返回给用户。
  4. 使用broadcast的分发方式,只需要把customer的数据广播给每个消费者。Lineorder的数不需要重新分发。因为lineorder的数据量比customer大的多,应该避免对lineorder的数据进行分发,这种执行计划非常适合星型模型的数据。

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

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

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

  1. 实例1、2上的p002/p003进程作为生产者,几乎平均扫描customer的1/4记录,把每一条记录广播给4个消费者PX进程,发送的记录数之和为6m行。通过table queue0(TQ_ID=0),每个作为消费者的p000/p001进程,接收了完整的1。5m行customer记录,接收的记录数之和为 6m行。
  2. 实例1、2上的p000/p0001进程作为生产者,通过table queue1(TQ_ID=1),把聚合的一条结果记录发给作为消费者的QC。QC作为消费者,接收了4行记录。

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

  1. DFO代表Data Flow Operator,是执行计划中可以并行执行的操作。一个QC代表一棵DFO树(tree),包含多个DFO;同一个QC中所有并行操作的DFO_NUMBER是相同的,此例中,所有DFO_NUMBER为1。执行计划包含多个QC的例子也不少见,比如使用unionall的语句,unionall每个分支都是独立的DFO树,不同的DFO树之间可以并行执行。本篇文章仅讨论执行计划只有一个QC的情况。
  2. TQ代表table queue,用以PX进程之间或者和QC通信连接。以上执行计划中,table queue0为PX进程之间的连接,table queue1为PX进程和QC之间的连接。生产者通过table queue分发数据,消费者从tablequeue接收数据。不同的table queue编号,代表了不同的数据分发。通过table queue,我们可以理解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进程之间,同一时间只能有一个活跃的数据分发。如果PX进程在执行计划中需要多次分发数据,可能需要在执行计划插入一些阻塞点,比如BUFFERSORT和HASHJOINBUFFERED这两个操作,保证上一次的数据分发完成之后,才开始下一次分发。在后面的章节,我将会说明这些阻塞点带来什么影响。这个例子中,tablequeue0和1可以同时工作是因为:tablequeue0是两组PX进程之间的链接,tablequeue1为PX进程和QC之间的连接,tablequeue0与tablequeue1是相互独立的,因此 可以同时进行。
  • PX进程之间或者与QC的连接至少存在一个(单节点下至多三个,RAC环境下至多四个)消息缓冲区用于进程间数据交互,该消息缓冲区默认在Largepool中分配(如果没有配置Largepool则在Sharedpool中分配)。多个缓冲区是为了实现异步通信,提高性能。
  • 每个消息缓冲区的大小由参数parallel_execution_message_size控制,默认为16k。
  • 当两个进程都在同一个节点的时候,通过在Largepool(如果没有配置Largepool则Sharedpool)中传递和接收消息缓冲进行数据交互。当两个进程位于不同节点时。通过RAC心跳网络进行数据交互,其中一方接收的数据需要缓存在本地Largepool(如果没有配置Largepool则Sharedpool)里面。

小结

为了说明并行执行的生产者--消费者模型是如何工作的,我使用了broad cast分发,QC分配两组PX进程,一组为生产者,一组为消费者。QC和PX进程之间,两组PX进程之间通过table queue进行数据分发,协同完成整个并行执行计划。视图V$PQ_TQSTAT记录了并行执行过程中,数据是如何分发的。通过对DFO,table queue的描述,我阐述生产者-­‐消费者模型的工作原理和通信过程,或许有些描述对你来说过于突然,不用担心,后面的章节我会通过更多的例子来辅助理解。

   
2184 次浏览       35
相关文章

基于EA的数据库建模
数据流建模(EA指南)
“数据湖”:概念、特征、架构与案例
在线商城数据库系统设计 思路+效果
 
相关文档

Greenplum数据库基础培训
MySQL5.1性能优化方案
某电商数据中台架构实践
MySQL高扩展架构设计
相关课程

数据治理、数据架构及数据标准
MongoDB实战课程
并发、大容量、高性能数据库设计与优化
PostgreSQL数据库实战培训
最新活动计划
嵌入式软件架构设计 12-11[北京]
LLM大模型与智能体开发实战 12-18[北京]
嵌入式软件测试 12-25[北京]
AI原生应用的微服务架构 1-9[北京]
AI大模型编写高质量代码 1-14[北京]
需求分析与管理 1-22[北京]

MySQL索引背后的数据结构
MySQL性能调优与架构设计
SQL Server数据库备份与恢复
让数据库飞起来 10大DB2优化
oracle的临时表空间写满磁盘
数据库的跨平台设计
更多...   


并发、大容量、高性能数据库
高级数据库架构设计师
Hadoop原理与实践
Oracle 数据仓库
数据仓库和数据挖掘
Oracle数据库开发与管理


GE 区块链技术与实现培训
航天科工某子公司 Nodejs高级应用开发
中盛益华 卓越管理者必须具备的五项能力
某信息技术公司 Python培训
某博彩IT系统厂商 易用性测试与评估
中国邮储银行 测试成熟度模型集成(TMMI)
中物院 产品经理与产品管理
更多...