Oracle 中的并行系列(一)

| 为什么要用并行

Oracle DBA在某些场景下进行SQL优化,会选择使用并行以消耗更多系统资源为代价,来提升SQL语句的响应时间。这些场景大部分时候是数据仓库或者DSS(决策支持系统)类似的数据密集行操作,当然部分在线事务处理系统(OLTP)有些时候也会选择并行执行的方式。并行有点类似分解任务的思维,即多个进程相互协调完成查询任务中的其中一小部分任务,而不是一个进程完成查询任务的所有工作。

| 什么时候使用并行

并行执行旨在充分利用可用的硬件资源; 如果没有足够的资源,那么并行执行不会产生任何好处,实际上可能会引起或者加重性能问题。一般情况下我们什么样的系统环境可以容许我们使用并行优化SQL语句的响应时间,常用判断标准如下:

(1)足够多逻辑CPU数量并且剩余较多空闲CPU,CPU(未充分利用或间歇使用的CPU)使用率低于30%的系统。

(2)基线负载情况下富余足够的存储IO带宽。

(3)有足够的内存来支持额外的内存密集型操作的进程,这些进程会执行一些排序,散列或I / O缓冲等。

如果我们的系统不满足上述指标,并行执行可能不会显着提高性能。而且,并行执行带来的额外开销可能还会降低高压力系统或I / O带宽较小的系统的系统性能。除此以外我们还需要考虑到语句执行计划的优劣和数据的倾斜度可能也会造成并行效果不明显的后果。

针对短频快的查询和事务(通常是秒级或者毫秒级),对于这些SQL语句我们通常并不会选择使用并行。因为很多时候并行进程间的信息传递任务协调成本可能会抵消并行带来的效益,最糟糕的情况是SQL语句执行效率开并行可能比不开并行还要低。

| 哪些操作可以使用并行

  • 数据扫描策略,例如:全表扫描,索引快速全扫描,分区索引范围扫描。

  • 表连接方式,例如常见的:排序合并,嵌套循环,哈希连接和星型联结转换。

  • DDL操作,例如:CREATE TABLE AS SELECT,     CREATE INDEX, REBUILD INDEX, REBUILD INDEX PARTITION, MOVE/SPLIT/COALESCE     PARTITION。

  • DML操作,例如:INSERT AS SELECT, UPDATE, DELETE和MERGE 等操作.

  • 查询操作,例如:DDL或者DML语句中附带的查询操作或者子查询。

  • 其他操作,例如:SQL*Loader,GROUP BY, NOT IN, SELECT DISTINCT, UNION, UNION ALL, CUBE,     ROLLUP和聚合表函数等。

| oracle数据库使用的并行方式

oracle数据库并行采用生产者-消费者模型的方式,生产者和消费者之间的数据并行分发方式有broadcast, hash 和12c数据库环境引入的replicate, 和更加智能的adaptive 分发方式。这四种分发方式详细介绍可以参考沃趣科技-魏兴华写的另外一篇文章http://blog.itpub.net/28218939/viewspace-1989259/。

| 看懂并行执行计划

以下为我们常见的开了并行的SQL执行计划,我们发现并行SQL的执行计划相对于普通未开并行的执行计划还是有很大差异。我们除了需要知道生产消费者间的数据分发方式还需要知道一些新名词:Table Queues(TQ)、DFOs(data flow operations)、DFOTrees、QC等。

Table Queues : TQ 是英文 table queue的缩写, TQ用以 PX 进程之间或者是PX与QC之间的通信连接。生产者通过 table queue 分发数据, 消费者从 table queue 接收数据。不同的 table queue 编号, 代表了不同的数据分发Table Queue。

DFOs (data flow operations):DFO 代表 Data Flow Operator, 表示一个可以并行执行的操作。

DFO Trees:一个DFO Tree可以包含一个或者多个相互联系的DFO;同一个DFO Tree中所有的DFO NUMBER都相同;值得注意的是不同的 DFO Tree间的DFO可以并行执行。

QC: 负责给PX进程分配工作,对PX进程进行统一的管理和调度。

细心的同学很容易发现我们执行计划中的Name列中显示Table queue 后面编号是有序的,一般情况下这个编号可以认为是数据分发的顺序.。理解执行计划中的并行操作执行的先后顺序原则为跟随Table queue 的数字顺序。请注意DFO Number并不能代表并行执行的先后顺序。

Id 1-8: 表示由两个DFO组成的DFO Tree,DFONUMBER为3。第一个DFO(TQ=0)一组PX进程进行LJL1表的并行扫描通过(:TQ30000)虚拟表向另外一组PX进程分发数据(Id 5-8)。第二个DFO(TQ=1)一组PX进程通过读取(:TQ30000)虚拟表的数据(Id 4)并进行HASH UNIOUE操作后通过写入虚拟表(:TQ30001)向查询协调器QC发送数据集。

Id 9-14: 代表第二颗DFO Tree,它包含一个DFO;Name列中的TQ10000可以理解为DFO NUMBER=1,TQ=0。

Id15-20: 代表第三颗DFO Tree,DFO NUMBER=2,TQ=0表示也由单个DFO操作组成。

除此之外我们我们发现上述执行计划多了TQ列,IN-OUT列,PQ Distrib列。TQ列我们上面已经解释过不再赘述;

IN-OUT列表示数据的流动和传递方式:

PCWP: Parallel Combine with Parent. 

PCWC: Parallel Combine wth Child.  

P->S: Parallel to Serial.

S->P: Serial to Parallel.

P->P: Parallel to Parallel. Inter-operationparallism.

PQ Distrib列:

QC(Rand): 所有生产者以random分发方式将它们的行发送到查询协调器QC;

HASH: 生产者并行进程使用HASH方式向并行消费者分发数据;

文章篇幅有限,到这里我们大致知道了简单的并行执行流程。但是实际使用中场景可能远没有这么简单,我们可能还会遇到数据倾斜 ,并行降级,并行失效,分发方式不合理,BUFFERSORT, HASH JOIN BUFFERED阻塞等情况,下篇文章我们会介绍。

| 作者简介

刘金龙·沃趣科技高级数据库技术专家

精通Oracle内部体系结构原理,擅长Oracle数据库性能调优、故障分析、定位以及解决,是国内最先接触并成功搭建测试12c R2 sharding 的DBA之一。

猜你喜欢

转载自blog.csdn.net/woqutechteam/article/details/84869847
今日推荐