本文为Oracle 19c VLDB and Partitioning Guide第8章Using Parallel Execution的读书笔记。

并行执行是通过使用多个进程将多个 CPU 和 I/O 资源应用于执行单个 SQL 语句的能力。

8.1 Parallel Execution Concepts

并行执行允许将多个 CPU 和 I/O 资源应用于单个 SQL 语句的执行。

并行执行通常用于决策支持系统 (DSS) 和数据仓库,可显着减少数据密集型操作的响应时间。 也可以在联机事务处理 (OLTP) 系统上实现并行执行,以进行批处理或模式维护操作,例如创建索引。

并行执行有时称为并行性(parallelism)。 并行性是一种分解任务的想法,这样,多个进程同时完成部分工作,而不是一个进程完成查询中的所有工作。 例如,当四个进程结合起来计算一年的总销售额时,每个进程处理一年中的一个季度,而不是一个进程自己处理所有四个季度。

并行执行改进了以下方面的处理:

  • 需要大表扫描、连接或分区索引扫描的查询
  • 创建大型索引
  • 创建大表,包括物化视图
  • 批量插入、更新、合并和删除

8.1.1 When to Implement Parallel Execution

并行执行用于通过利用硬件中的 CPU 和 I/O 能力来减少查询的执行时间。

在以下情况下,并行执行是比串行执行更好的选择:

  • 该查询引用了一个大型数据集。
  • 并发性低。
  • 实际耗时很重要。

并行执行使许多进程协同工作以执行单个操作,例如 SQL 查询。 并行执行使具有以下所有特征的系统受益:

  • 对称多处理器 (SMP)、集群或大规模并行系统
  • 足够的 I/O 带宽
  • 未充分利用或间歇性使用的 CPU(例如,CPU 使用率通常低于 30% 的系统)
  • 足够的内存来支持额外的内存密集型进程,例如排序、散列和 I/O 缓冲区

如果您的系统缺少这些特征中的任何一个,则并行执行可能不会显著提高性能。 事实上,并行执行可能会降低过度使用的系统或具有小 I/O 带宽的系统的系统性能。

在 DSS 和数据仓库环境中可以观察到并行执行的好处。 OLTP 系统还可以在批处理和模式维护操作(例如创建索引)期间从并行执行中受益。 表征 OLTP 应用程序的普通简单 DML 或 SELECT 语句不会从并行执行中获得任何好处。

按照这里和Wiki的说法,SELECT是不属于DML,而属于DQL

8.1.2 When Not to Implement Parallel Execution

串行执行与并行执行的不同之处在于只有一个进程执行单个数据库操作,例如 SQL 查询。

在以下情况下,串行执行是比并行执行更好的选择:

  • 该查询引用了一个小型数据集。
  • 有高并发。
  • 效率很重要。

并行执行通常不适用于:

  • 典型查询或事务非常短(几秒钟或更短)的环境。
    这包括大多数在线交易系统。并行执行在这些环境中没有用处,因为协调并行执行服务器会产生成本;对于短事务,这种协调的成本可能超过并行的好处。
  • 大量使用 CPU、内存或 I/O 资源的环境。
    并行执行旨在利用额外的可用硬件资源;如果没有此类资源可用,则并行执行不会产生任何好处,并且实际上可能会损害性能。

8.1.3 Fundamental Hardware Requirements

并行执行旨在有效地使用多个 CPU 和磁盘来快速回答查询。

它本质上是非常 I/O 密集型的。为了实现最佳性能,硬件配置中的每个组件的大小必须保持相同的吞吐量水平:从计算节点中的 CPU 和主机总线适配器 (HBA),到交换机,再到 I/O 子系统,包括存储控制器和物理磁盘。如果系统是 Oracle Real Application Clusters (Oracle RAC) 系统,则还必须适当调整互连大小。最薄弱的环节将限制配置中操作的性能和可扩展性

建议测量硬件配置在没有 Oracle 数据库的情况下可以实现的最大 I/O 性能。您可以将此测量用作未来系统性能评估的基准。请记住,并行执行不可能实现比底层硬件能够承受的更好的 I/O 吞吐量。 Oracle 数据库提供了一个名为 Orion 的免费校准工具,旨在通过模拟 Oracle I/O 工作负载来测量系统的 I/O 性能。并行执行通常执行大型随机 I/O

8.1.4 How Parallel Execution Works

并行执行分解了一项任务,因此,不是一个进程完成查询中的所有工作,而是许多进程同时完成一部分工作。

8.1.4.1 Parallel Execution of SQL Statements

每条 SQL 语句在解析时都会经历一个优化和并行化过程。

如果确定该语句是并行执行的,那么执行计划中会出现以下步骤:

  • 用户会话或影子进程扮演协调器的角色,通常称为查询协调器 (QC) 或并行执行 (PX) 协调器。 QC 是启动并行 SQL 语句的会话。
  • PX 协调器获取必要数量的进程,称为并行执行 (PX) 服务器。 PX 服务器是代表发起会话并行执行工作的各个进程。
  • SQL 语句作为一系列操作执行,例如全表扫描或 ORDER BY 子句。如果可能,每个操作都并行执行。
  • 当 PX 服务器完成执行语句时,PX 协调器将执行任何无法并行执行的工作部分。例如,使用 SUM() 操作的并行查询需要添加由每个 PX 服务器计算的各个小计。
  • 最后,PX 协调器将结果返回给用户。

8.1.4.2 Producer/Consumer Model

并行执行使用生产者/消费者模型。

并行执行计划作为一系列生产者/消费者操作来执行。 为后续操作生成数据的并行执行 (PX) 服务器称为生产者,需要其他操作输出的 PX 服务器称为消费者。 每个生产者或消费者并行操作由一组称为 PX 服务器集的 PX 服务器执行。 PX 服务器集中的 PX 服务器数量称为并行度 (DOP)。 PX 服务器集的基本工作单元称为数据流操作 (DFO)。

一个 PX 协调器可以有多个级别的生产者/消费者操作(多个 DFO),但一个 PX 协调器的 PX 服务器集的数量限制为两个。 因此,在某个时间点,一个 PX 协调器只能激活两个 PX 服务器集。 因此,DFO 中的操作和 DFO 之间的操作都存在并行性。 单个 DFO 的并行度称为操作内并行度,DFO 之间的并行度称为操作间并行度。 为了说明操作内和操作间的并行性,请考虑以下语句:

SELECT * FROM employees ORDER BY last_name;

执行计划实现了对雇员表的全面扫描。 此操作之后是根据 last_name 列的值对检索到的行进行排序。 假设 last_name 列没有被索引。 还假设查询的 DOP 设置为 4,这意味着四个并行执行服务器可以为任何给定操作处于活动状态。

图 8-1 说明了示例查询的并行执行。

图 8-1 操作间并行和动态分区

如图 8-1 所示,尽管 DOP 为 4,但实际上有 8 个 PX 服务器参与了查询。这是因为生产者和消费者操作员可以同时执行(互操作并行性)。

此外,扫描操作中涉及的所有 PX 服务器都将行发送到执行 SORT 操作的相应 PX 服务器。 如果 PX 服务器扫描的行包含 A 和 G 之间的 last_name 列的值,则该行将发送到第一个 ORDER BY 并行执行服务器。 当扫描操作完成后,排序进程可以将排序后的结果返回给查询协调器,查询协调器将完整的查询结果返回给用户。

8.1.4.3 Granules of Parallelism

并行性的基本工作单元是称为颗粒。

Oracle 数据库将并行执行的操作(例如表扫描或索引创建)划分为颗粒。 并行执行 (PX) 服务器一次执行一个颗粒的操作。 颗粒的数量及其大小与并行度 (DOP) 相关。 颗粒的数量也会影响工作在 PX 服务器之间的平衡程度。

8.1.4.3.1 Block Range Granules

块范围颗粒是大多数并行操作的基本单元,即使在分区表上也是如此。从 Oracle 数据库的角度来看,并行度与分区数无关。

块范围颗粒是表中物理块的范围。 Oracle 数据库在运行时计算颗粒的数量和大小,以优化和平衡所有受影响的并行执行 (PX) 服务器的工作分配。颗粒的数量和大小取决于对象的大小和 DOP。块范围颗粒不依赖于表或索引的静态预分配。在计算粒度期间,Oracle 数据库将 DOP 考虑在内,并尝试将来自不同数据文件的粒度分配给每个 PX 服务器,以尽可能避免争用。此外,Oracle 数据库考虑大规模并行处理 (MPP) 系统上的颗粒的磁盘亲和性,以利用 PX 服务器和磁盘之间的物理亲和性

8.1.4.3.2 Partition Granules

当使用分区颗粒时,并行执行 (PX) 服务器在表或索引的整个分区或子分区上工作。

因为在创建表或索引时,分区颗粒是由表或索引的结构静态确定的,所以分区颗粒不能像块颗粒那样为您提供并行执行操作的灵活性。最大允许并行度 (DOP) 是分区数。这可能会限制系统的利用率和跨 PX 服务器的负载平衡。

当使用分区颗粒对表或索引进行并行访问时,您应该使用相对大量的分区,最好是 DOP 的 3 倍,以便 Oracle 数据库可以有效地平衡 PX 服务器之间的工作。

分区颗粒是并行索引范围扫描的基本单元,查询优化器选择使用分区连接的两个等分区表之间的连接,以及修改分区对象的多个分区的并行操作。这些操作包括并行创建分区索引和并行创建分区表。

您可以通过查看语句的执行计划来判断使用了哪些类型的颗粒。 表或索引访问上方的 PX BLOCK ITERATOR 行表示已使用块范围颗粒。 在下面的示例中,您可以在 SALES 表的 TABLE FULL ACCESS 上方的解释计划输出的第 7 行看到这一点。

-------------------------------------------------------------------------------------------------
|Id|      Operation          |  Name  |Rows|Bytes|Cost%CPU|  Time  |Pst|Pst|  TQ |INOUT|PQDistri|
-------------------------------------------------------------------------------------------------
| 0|SELECT STATEMENT         |        |  17| 153 |565(100)|00:00:07|   |   |     |     |        |
| 1| PX COORDINATOR          |        |    |     |        |        |   |   |     |     |        |
| 2|  PX SEND QC(RANDOM)     |:TQ10001|  17| 153 |565(100)|00:00:07|   |   |Q1,01|P->S |QC(RAND)|
| 3|   HASH GROUP BY         |        |  17| 153 |565(100)|00:00:07|   |   |Q1,01|PCWP |        |
| 4|    PX RECEIVE           |        |  17| 153 |565(100)|00:00:07|   |   |Q1,01|PCWP |        |
| 5|     PX SEND HASH        |:TQ10000|  17| 153 |565(100)|00:00:07|   |   |Q1,00|P->P | HASH   |
| 6|      HASH GROUP BY      |        |  17| 153 |565(100)|00:00:07|   |   |Q1,00|PCWP |        |
| 7|       PX BLOCK ITERATOR |        | 10M| 85M | 60(97) |00:00:01| 1 | 16|Q1,00|PCWC |        |
|*8|        TABLE ACCESS FULL|  SALES | 10M| 85M | 60(97) |00:00:01| 1 | 16|Q1,00|PCWP |        |
-------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------
8 - filter("CUST_ID"<=22810 AND "CUST_ID">=22300)

使用分区颗粒时,您会在说明计划输出中看到表或索引访问上方的 PX PARTITION RANGE 行。 在下面示例的第 6 行,计划具有 PX PARTITION RANGE ALL,因为该语句访问表中的所有 16 个分区。 如果没有访问所有分区,它只会显示 PX PARTITION RANGE。

---------------------------------------------------------------------------------------------------------
|Id|      Operation                    |  Name    |Rows|Byte|Cost%CPU|  Time  |Ps|Ps|  TQ |INOU|PQDistri|
---------------------------------------------------------------------------------------------------------
| 0|SELECT STATEMENT                   |          |  17| 153|   2(50)|00:00:01|  |  |     |    |        |
| 1| PX COORDINATOR                    |          |    |    |        |        |  |  |     |    |        |
| 2|  PX SEND QC(RANDOM)               |:TQ10001  |  17| 153|   2(50)|00:00:01|  |  |Q1,01|P->S|QC(RAND)|
| 3|   HASH GROUP BY                   |          |  17| 153|   2(50)|00:00:01|  |  |Q1,01|PCWP|        |
| 4|    PX RECEIVE                     |          |  26| 234|    1(0)|00:00:01|  |  |Q1,01|PCWP|        |
| 5|     PX SEND HASH                  |:TQ10000  |  26| 234|    1(0)|00:00:01|  |  |Q1,00|P->P| HASH   |
| 6|      PX PARTITION RANGE ALL       |          |  26| 234|    1(0)|00:00:01|  |  |Q1,00|PCWP|        |
| 7|       TABLEACCESSLOCAL INDEX ROWID|SALES     |  26| 234|    1(0)|00:00:01| 1|16|Q1,00|PCWC|        |
|*8|        INDEX RANGE SCAN           |SALES_CUST|  26|    |    1(0)|00:00:01| 1|16|Q1,00|PCWP|        |
---------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------
8 - access("CUST_ID"<=22810 AND "CUST_ID">=22300)

8.1.4.4 Distribution Methods Between Producers and Consumers

分发方法是将数据从一个并行执行 (PX) 服务器集发送(或重新分发)到另一台服务器的方法。

以下是并行执行中最常用的分发方法。

  • 哈希分布
    哈希分发方法在行中的一个或多个列上使用散列函数,然后确定生产者应该将行发送到哪里的消费者。这种分发试图根据哈希值在消费者之间平均分配工作。

  • 广播分发
    在广播分发方法中,每个生产者将所有行发送给所有消费者。当join操作中左侧的结果集较小且广播所有行的成本不高时使用此方法。在这种情况下,连接右侧的结果集不需要分发;分配给连接操作的消费者 PX 服务器可以扫描右侧并执行连接。

  • 范围分发
    范围分发主要用于并行排序操作。在此方法中,每个生产者将具有一系列值的行发送给同一消费者。这就是图 8-1 中使用的方法。

  • 混合哈希分发
    混合哈希是一种用于连接操作的自适应分布方法。实际的分发方式由优化器在运行时根据连接左侧结果集的大小来决定。对从左侧返回的行数进行计数并根据阈值进行检查。当行数小于或等于阈值时,join的左侧使用广播分发,右侧不分发,因为分配给join操作的相同消费者PX服务器扫描右侧和执行连接。当从左侧返回的行数高于阈值时,连接的两边都使用哈希分发。

虽然很分区很类似,但这里说的是分发

为了确定分发方法,并行执行 (PX) 协调器检查 SQL 语句的执行计划中的每个操作,然后确定操作所操作的行必须在 PX 服务器之间重新分发的方式。 作为并行查询的示例,请考虑示例 8-1 中的查询。 图 8-2 说明了示例 8-1 中查询的数据流或查询计划,示例 8-2 显示了相同查询的解释计划输出。

查询计划显示 PX 协调器选择了一种自适应分布方法。 假设优化器在运行时选择散列分布,执行过程如下:为查询分配两组 PX 服务器,SS1 和 SS2,由于指定语句 DOP 的 PARALLEL 提示,每个服务器组有四个 PX 服务器 .

PX 集SS1 首先扫描表customers 并将行发送到SS2,SS2 在这些行上构建一个哈希表。 换句话说,SS2 中的消费者和 SS1 中的生产者同时工作:一个并行扫描客户,另一个并行消费行并构建哈希表以启用哈希联接。 这是操作间并行性的一个示例。

SS1 中的 PX 服务器进程扫描客户表中的一行后,应该将其发送到 SS2 中的哪个 PX 服务器进程? 在这种情况下,从执行客户并行扫描的 SS1 向上流入执行并行哈希连接的 SS2 的行的重新分发是通过连接列上的哈希分配完成的。 也就是说,扫描客户的 PX 服务器进程会根据列customers.cust_id 的值计算哈希函数,以决定将其发送到 SS2 中的哪个 PX 服务器进程。 使用的重新分发方法明确显示在查询的 EXPLAIN PLAN 的 Distrib 列中。 在图 8-2 中,可以在 EXPLAIN PLAN 的第 5、9 和 14 行看到这一点。

SS1 扫描完整个customers 表后,并行扫描sales 表。 它将其行发送到 SS2 中的 PX 服务器,然后执行探测以并行完成哈希连接。 这些 PX 服务器还在JOIN后执行 GROUP BY 操作。 在 SS1 并行扫描了 sales 表并将行发送到 SS2 之后,它切换到并行执行最后的 group by 操作。 此时,SS2 中的 PX 服务器使用哈希分发将它们的行发送到 SS1 上的 PX 服务器,以进行分组操作。 这就是两个服务器集如何同时运行以实现查询树中各种运算符之间的操作间并行性。

图 8-2 连接表的数据流图

示例 8-1 为客户和销售查询运行解释计划

EXPLAIN PLAN FOR
SELECT /*+ PARALLEL(4) */ customers.cust_first_name, customers.cust_last_name, MAX(QUANTITY_SOLD), AVG(QUANTITY_SOLD)FROM sales, customersWHERE sales.cust_id=customers.cust_idGROUP BY customers.cust_first_name, customers.cust_last_name;Explained.

示例 8-2 有关客户和销售的查询的解释计划输出

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3260900439
---------------------------------------------------------------------------------------------------------------------------------------
|Id  |Operation                      |Name     |Rows  | Bytes |TempSpc|Cost (%CPU)| Time     |Pstart|Pstop |   TQ  |IN-OUT|PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------
|  0 |SELECT STATEMENT               |         |  960 | 26880 |       |    6  (34)| 00:00:01 |      |      |       |      |           |
|  1 | PX COORDINATOR                |         |      |       |       |           |          |      |      |       |      |           |
|  2 |  PX SEND QC (RANDOM)          |:TQ10003 |  960 | 26880 |       |    6  (34)| 00:00:01 |      |      | Q1,03 | P->S |QC (RAND)  |
|  3 |   HASH GROUP BY               |         |  960 | 26880 | 50000 |    6  (34)| 00:00:01 |      |      | Q1,03 | PCWP |           |
|  4 |    PX RECEIVE                 |         |  960 | 26880 |       |    6  (34)| 00:00:01 |      |      | Q1,03 | PCWP |           |
|  5 |     PX SEND HASH              |:TQ10002 |  960 | 26880 |       |    6  (34)| 00:00:01 |      |      | Q1,02 | P->P |HASH       |
|  6 |      HASH GROUP BY            |         |  960 | 26880 | 50000 |    6  (34)| 00:00:01 |      |      | Q1,02 | PCWP |           |
|* 7 |       HASH JOIN               |         |  960 | 26880 |       |    5  (20)| 00:00:01 |      |      | Q1,02 | PCWP |           |
|  8 |        PX RECEIVE             |         |  630 | 12600 |       |    2   (0)| 00:00:01 |      |      | Q1,02 | PCWP |           |
|  9 |         PX SEND HYBRID HASH   |:TQ10000 |  630 | 12600 |       |    2   (0)| 00:00:01 |      |      | Q1,00 | P->P |HYBRID HASH|
| 10 |          STATISTICS COLLECTOR |         |      |       |       |           |          |      |      | Q1,00 | PCWC |           |
| 11 |           PX BLOCK ITERATOR   |         |  630 | 12600 |       |    2   (0)| 00:00:01 |      |      | Q1,00 | PCWC |           |
| 12 |            TABLE ACCESS FULL  |CUSTOMERS|  630 | 12600 |       |    2   (0)| 00:00:01 |      |      | Q1,00 | PCWP |           |
| 13 |        PX RECEIVE             |         |  960 |  7680 |       |    2   (0)| 00:00:01 |      |      | Q1,02 | PCWP |           |
| 14 |         PX SEND HYBRID HASH   |:TQ10001 |  960 |  7680 |       |    2   (0)| 00:00:01 |      |      | Q1,01 | P->P |HYBRID HASH|
| 15 |          PX BLOCK ITERATOR    |         |  960 |  7680 |       |    2   (0)| 00:00:01 |    1 |   16 | Q1,01 | PCWC |           |
| 16 |           TABLE ACCESS FULL   |SALES    |  960 |  7680 |       |    2   (0)| 00:00:01 |    1 |   16 | Q1,01 | PCWP |           |
---------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("SALES"."CUST_ID"="CUSTOMERS"."CUST_ID")
Note
------ Degree of Parallelism is 4 because of hint

8.1.4.5 How Parallel Execution Servers Communicate

为了并行执行查询,Oracle 数据库通常会创建一组生产者并行执行服务器和一组消费者并行执行服务器。

生产者服务器从表中检索行,消费者服务器对这些行执行连接、排序、DML 和 DDL 等操作。 生产者集中的每个服务器都与消费者集中的每个服务器都有连接。 并行执行服务器之间的虚拟连接数随着并行度的平方而增加。

每个通信通道至少有一个,有时最多四个内存缓冲区,它们是从共享池中分配的。 多个内存缓冲区有助于并行执行服务器之间的异步通信。

单实例环境对每个通信通道最多使用三个缓冲区。 Oracle Real Application Clusters 环境对每个通道最多使用四个缓冲区。 图 8-3 说明了消息缓冲区以及生产者并行执行服务器如何连接到消费者并行执行服务器。

图 8-3 并行执行服务器连接和缓冲区

当连接在同一实例上的两个进程之间时,服务器通过在内存中(在共享池中)来回传递缓冲区进行通信。 当连接在不同实例中的进程之间时,使用外部高速网络协议通过互连发送消息。 在图 8-3 中,DOP 等于并行执行服务器的数量,在本例中为 n。 图 8-3 没有显示并行执行协调器。 每个并行执行服务器实际上都有一个到并行执行协调器的附加连接。 使用并行执行时,充分调整共享池的大小很重要。 如果共享池中没有足够的可用空间来为并行服务器分配必要的内存缓冲区,它将无法启动。

8.1.5 Parallel Execution Server Pool

当一个实例启动时,Oracle 数据库创建一个并行执行服务器池,可用于任何并行操作。

初始化参数 PARALLEL_MIN_SERVERS 指定 Oracle 数据库在实例启动时创建的并行执行服务器的数量。

在执行并行操作时,并行执行协调器从池中获取并行执行服务器并将它们分配给该操作。如有必要,Oracle 数据库可以为操作创建额外的并行执行服务器。这些并行执行服务器在整个执行过程中与操作保持一致。处理完语句后,并行执行服务器返回到池中。

如果并行操作的数量增加,Oracle 数据库会创建额外的并行执行服务器来处理传入请求。但是,Oracle 数据库为实例创建的并行执行服务器永远不会超过初始化参数 PARALLEL_MAX_SERVERS 指定的值。

如果并行操作的数量减少,Oracle 数据库将终止任何已空闲达阈值时间间隔的并行执行服务器。无论并行执行服务器空闲多长时间,Oracle 数据库都不会将池的大小减小到小于 PARALLEL_MIN_SERVERS 的值。

以下为一个4 OCPU的OCI DBCS上的配置:

SQL> show parameter PARALLEL_MIN_SERVERSNAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
parallel_min_servers                 integer     32
SQL> show parameter PARALLEL_MAX_SERVERSNAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
parallel_max_servers                 integer     320
SQL> show parameter cpu_countNAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cpu_count                            integer     8

8.1.5.1 Processing without Enough Parallel Execution Servers

Oracle 数据库可以处理少于请求数量的并行操作。

如果池中的所有并行执行服务器都被占用并且已经启动了最大数量的并行执行服务器,则并行执行协调器切换到串行处理。

8.1.6 Balancing the Workload to Optimize Performance

为了优化性能,所有并行执行服务器应该具有相同的工作负载。

对于按块范围或并行执行服务器并行运行的 SQL 语句,工作负载在并行执行服务器之间动态分配。 这最大限度地减少了工作负载倾斜,当某些并行执行服务器执行的工作明显多于其他进程时,就会发生这种情况。

对于相对较少的按分区并行执行的 SQL 语句,如果工作负载在分区之间均匀分布,则可以通过将并行执行服务器的数量与分区数量相匹配或选择一个 DOP (使得分区数是进程数的倍数)来优化性能。 这适用于在 Oracle9i 之前创建的表上的分区连接和并行 DML。 有关详细信息,请参阅对并行度的限制。

例如,假设一张表有 16 个分区,并行操作将工作平均分配在它们之间。 您可以使用 16 个并行执行服务器(DOP 等于 16)在大约十分之一的时间内完成一个进程所需的时间。 您还可以使用五个进程在五分之一的时间内完成工作,或者使用两个进程在二分之一的时间内完成工作。

但是,如果您使用 15 个进程在 16 个分区上工作,那么第一个在一个分区上完成工作的进程之后会开始在第 16 个分区上工作; 而其他进程完成其工作后就会变得空闲。 当工作在分区之间平均分配时,此配置不会提供良好的性能。 当工作分配不均时,性能会根据留到最后的分区的工作量比其他分区多还是少而有所不同。

同样,假设您使用六个进程在 16 个分区上工作,并且工作被平均分配。 在这种情况下,每个进程在完成其第一个分区后在第二个分区上工作,但只有四个进程在第三个分区上工作,而其他两个保持空闲状态。

通常,您不能假设在给定数量的分区 (N) 和给定数量的并行执行服务器 § 上执行并行操作所需的时间等于 N 除以 P。这个公式没有考虑某些可能性:当其他进程正在完成最后一个分区的工作时,进程可能必须等待。 但是,通过选择适当的 DOP,您可以最大限度地减少工作负载偏差并优化性能。

8.1.7 Multiple Parallelizers

执行计划中的每个并行执行 (PX) 协调器称为并行器。

SQL 语句使用的 PX 服务器的数量由语句并行度 (DOP) 和并行器的数量决定。 由于并行器的 PX 服务器集数量限制为两个,因此大多数语句的 PX 服务器数量为 DOP2。 有些语句可以有多个并行器。 因为每个并行器可以使用两个 PX 服务器集,所以这些语句的 PX 服务器数量可以超过 DOP2。 您可以通过查看 EXPLAIN PLAN 来识别这些陈述。 如果计划有多个 PX 协调器,则意味着该语句有多个并行器。

SQL 语句使用多个并行器的一些示例情况是子查询分解、分组集、星型查询、内存中聚合和非相关子查询

SQL 语句中的多个并行器可以同时激活,也可以一个接一个地激活,具体取决于执行计划。

具有单个并行器的语句在执行开始时分配所需数量的 PX 服务器,并在语句完成之前保持这些分配的 PX 服务器不释放。 这可确保在整个执行过程中 PX 服务器的数量是恒定的。 具有多个并行器的语句是不同的,因为它们在每个并行器启动时分配 PX 服务器。 由于并行器可以在执行期间的不同时间启动,因此每个并行器可能会根据系统中可用进程的数量与不同数量的 PX 服务器一起运行。

如果同时执行多个并行器,则该语句可以使用比 DOP*2 更多的 PX 服务器。

V$PQ_SESSTAT 视图在 STATISTIC 列中显示了并行器的数量。 数据流操作统计 DFO Trees 显示了并行器的数量。 Server Threads 统计信息显示同时用于 SQL 语句的 PX 服务器的最大数量。

8.1.8 Parallel Execution on Oracle RAC

默认情况下,在 Oracle RAC 环境中,并行执行的 SQL 语句可以跨集群中的所有节点运行。

要执行此跨节点或节点间并行执行,必须适当调整 Oracle RAC 环境中的互连大小,因为节点间并行执行可能会导致大量互连流量。 节点间并行执行不会随着配置容量过小的互连而扩展。

限制可用实例的数量

在 Oracle RAC 环境中,您可以使用服务来限制参与执行并行 SQL 语句的实例数量。 默认服务包括所有可用实例。 您可以创建任意数量的服务,每个服务都包含一个或多个实例。 当用户使用服务连接到数据库时,只有作为服务成员的实例上的 PX 服务器才能参与并行语句的执行。

要将并行执行限制为单个节点,可以将 PARALLEL_FORCE_LOCAL 初始化参数设置为 TRUE。 在这种情况下,只有会话连接到的实例上的 PX 服务器用于从该会话执行并行语句。 请注意,当此参数设置为 TRUE 时,在该实例上运行的所有并行语句都在本地执行,无论会话直接连接到实例还是使用服务连接。

Flex 集群上的并行执行

在弹性集群上执行的并行语句可以同时使用中心和叶节点。 由于用户会话只允许连接到中心节点,因此协调器进程(查询协调器或 PX 协调器)驻留在中心节点上,并且可以从集群中的任何节点使用 PX 服务器进程。 对于并行查询,任何节点上的任何 PX 服务器都可以参与语句的执行。 对于并行 DML 操作,只有中心节点上的 PX 服务器可以参与语句的 DML 部分的执行,因为仅允许中心节点执行 DML 操作。

当 DML 操作存在从叶子节点到中心节点的数据分布时,执行计划会指示这种分布。 在下面的例子中,数据被分发到第 5 行的中心节点,表示第 3 行的加载操作只在中心节点上执行。

8.2 Setting the Degree of Parallelism

并行度 (DOP) 是与单个操作关联的并行执行服务器的数量。

并行执行旨在有效地使用多个 CPU。 Oracle 数据库并行执行框架使您能够显式选择特定的并行度或依靠 Oracle 数据库自动控制它。

8.2.1 Manually Specifying the Degree of Parallelism

可以从 Oracle 数据库中为表和索引请求特定的并行度 (DOP)。

例如,您可以使用以下内容在表级别设置固定 DOP:

ALTER TABLE sales PARALLEL 8;
ALTER TABLE customers PARALLEL 4;

在此示例中,仅访问 sales 表的查询请求的 DOP 为 8,访问 customers 表的查询请求的 DOP 为 4。同时访问 sales 表和 customers 表的查询使用 8 的 DOP 进行处理,并可能分配 16 个并行执行 服务器(由于生产者/消费者模型)。 无论何时指定不同的 DOP,Oracle 数据库都会使用更高的 DOP。

您还可以使用语句级或对象级并行提示来请求特定的 DOP。

表或索引的 PARALLEL 子句中指定的 DOP 仅在 PARALLEL_DEGREE_POLICY 设置为 MANUAL (默认值)或 LIMITED 时生效。

语句的实际运行时 DOP 可以受 Oracle 数据库资源管理器的限制。

8.2.2 Default Degree of Parallelism

如果指定了 PARALLEL 子句但未列出并行度 (DOP),则对象获取默认 DOP。

例如,您可以使用以下 SQL 语句将表设置为默认 DOP。

ALTER TABLE sales PARALLEL;

默认并行度使用公式根据系统配置确定 DOP,如下所示:

  • 对于单个实例,DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT
  • 对于 Oracle RAC 配置,DOP = PARALLEL_THREADS_PER_CPU x sum(CPU_COUNT)

默认情况下,sum(CPU_COUNT) 是集群中的 CPU 总数。但是,如果您使用 Oracle RAC 服务来限制可以执行并行操作的节点数,则 sum(CPU_COUNT) 是属于该服务的节点上的 CPU 总数。例如,在 4 节点 Oracle RAC 集群上,每个节点有 8 个 CPU 内核且没有 Oracle RAC 服务,默认 DOP 为 2 x (8+8+8+8) = 64。

您还可以使用语句级或对象级并行提示请求默认 DOP。

表或索引的 PARALLEL 子句中指定的默认 DOP 只有在 PARALLEL_DEGREE_POLICY 设置为 MANUAL 时才生效

默认 DOP 算法旨在使用最大资源,并假设如果可以使用更多资源,则操作完成得更快。默认 DOP 以单用户工作负载为目标,不建议在多用户环境中使用

SQL 语句的实际运行时 DOP 可能受 Oracle 数据库资源管理器的限制。

8.2.3 Automatic Degree of Parallelism

自动并行度 (Auto DOP) 使 Oracle 数据库能够自动决定一条语句是否应该并行执行以及它应该使用什么 DOP。

以下是启用 Auto DOP 时并行语句处理的摘要。

  1. 发出一条 SQL 语句。
  2. 语句被解析,优化器确定执行计划。
  3. 检查由 PARALLEL_MIN_TIME_THRESHOLD (默认为10秒,如果使用IMCS则为1秒) 初始化参数指定的阈值限制。

如果预期执行时间小于阈值限制,则依次运行 SQL 语句。

如果预期执行时间大于阈值限制,则语句将根据优化器计算的 DOP 并行运行,包括任何已定义资源限制的分解。

8.2.4 Determining Degree of Parallelism in Auto DOP

使用自动并行度 (DOP),优化器会根据语句的资源需求自动确定语句的 DOP。

优化器使用所有扫描操作的成本,例如全表扫描或索引快速全扫描,以及执行计划中所有 CPU 操作的成本来确定必要的 DOP。

但是,优化器会限制实际的最大 DOP,以确保并行执行服务器不会使系统不堪重负。此限制由参数 PARALLEL_DEGREE_LIMIT 设置。此参数的默认值为 CPU,这意味着 DOP 受系统上 CPU 数量的限制。 (PARALLEL_THREADS_PER_CPU * sum(CPU_COUNT)),也称为默认 DOP。此默认 DOP 确保单个用户操作不会使系统不堪重负。通过调整此参数设置,您可以控制优化器可以为 SQL 语句选择的最大 DOP。如果使用 Oracle 数据库资源管理器来限制 DOP,优化器可以进一步限制可以选择的最大 DOP。

注意:PARALLEL_DEGREE_LIMIT 的值 AUTO 与值 CPU 具有相同的功能。

为了计算 SQL 语句的操作成本,Auto DOP 使用有关系统硬件特性的信息。 硬件特性包括 I/O 校准统计数据,因此应收集这些统计数据。

如果未运行 I/O 校准来收集所需的统计数据,则使用默认校准值来计算操作成本和 DOP。

可以使用 PL/SQL DBMS_RESOURCE_MANAGER.CALIBRATE_IO 过程收集 I/O 校准统计信息。 如果物理硬件没有改变,I/O 校准是一次性操作。

优化器确定的 DOP 显示在解释计划输出的注释部分中,如下面的解释计划输出所示,使用解释计划语句或 V$SQL_PLAN 可见。

EXPLAIN PLAN FOR
SELECT SUM(AMOUNT_SOLD) FROM SH.SALES;PLAN TABLE OUTPUT
Plan hash value: 1763145153----------------------------------------------------------------------------------------------------------------------
|Id| Operation              | Name     | Rows | Bytes| Cost (%CPU)| Time     | Pstart| Pstop|    TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------
| 0| SELECT STATEMENT       |          |     1|     4|     2   (0)| 00:00:01 |       |       |      |      |           |
| 1|  SORT AGGREGATE        |          |     1|     4|            |          |       |      |       |      |           |
| 2|   PX COORDINATOR       |          |      |      |            |          |       |      |       |      |           |
| 3|    PX SEND QC (RANDOM) | :TQ10000 |     1|     4|            |          |       |      |  Q1,00| P->S | QC (RAND) |
| 4|     SORT AGGREGATE     |          |     1|     4|            |          |       |      |  Q1,00| PCWP |           |
| 5|      PX BLOCK ITERATOR |          |   960|  3840|     2   (0)| 00:00:01 |     1 |    16|  Q1,00| PCWC |           |
| 6|       TABLE ACCESS FULL| SALES    |   960|  3840|     2   (0)| 00:00:01 |     1 |    16|  Q1,00| PCWP |           |
------------------------------------------------------------------------------------------------------------------------
Note
------ automatic DOP: Computed Degree of Parallelism is 4

如何校准I/O,以下过程参考这里:

SQL> col CALIBRATION_TIME for a20
SQL> select * from v$io_calibration_status;STATUS        CALIBRATION_TIME         CON_ID
------------- -------------------- ----------
NOT AVAILABLE                               0-- 以下PL/SQL的执行时间很长, 约10分钟
-- 输入参数的默认值:num_physical_disks=1,max_latency=20毫秒
Set serveroutput on size 1000000
Declare
Calc_lat number;
Calc_iops number;
Calc_mbps number;
Begin
Dbms_resource_manager.calibrate_io(&dsks,&maxlat, Calc_iops, Calc_mbps, Calc_lat);
Dbms_output.put_line('Max IOPS : '||Calc_iops);
Dbms_output.put_line('Max mbytes-per-sec: '||Calc_mbps);
Dbms_output.put_line('Calc. latency : '||Calc_lat);
End;
/输出如下:
max_iops = 19282
latency  = 1.065
max_mbps = 150
Max IOPS : 19282
Max mbytes-per-sec: 150
Calc. latency : 1.065000057220459PL/SQL procedure successfully completed.和实际值的对比:- max_iops,OCI服务显示的Theoretical max IOPS:19.2K,这个还是比较准的- max_mbps,我测试程序的值为114.624 mbps

8.2.5 Controlling Automatic Degree of Parallelism

有几个初始化参数可以控制自动并行度 (auto DOP)。 这些初始化参数包括 PARALLEL_DEGREE_POLICY(MANUAL)、PARALLEL_DEGREE_LIMIT(CPU)、PARALLEL_MIN_TIME_THRESHOLD(AUTO) 和 PARALLEL_MIN_DEGREE(1)。

初始化参数 PARALLEL_DEGREE_POLICY 控制是否启用 Auto DOP、并行语句排队和内存中并行执行。 此参数具有以下可能值:

  • MANUAL
    此设置禁用 Auto DOP、并行语句队列和内存中并行执行。 它将并行执行的行为恢复为 Oracle 数据库 11g 第 2 版 (11.2) 之前的行为,这是默认设置。
    使用 PARALLEL_DEGREE_POLICY 的默认设置 MANUAL,系统仅在对象上显式设置 DOP 或在 SQL 语句中指定并行提示时使用并行执行。 使用的 DOP 正是指定的。 不会发生并行语句排队和内存中并行执行。

  • LIMITED
    此设置为某些语句启用 Auto DOP,但禁用并行语句排队和内存中并行执行。 自动 DOP 仅适用于访问使用 PARALLEL 子句显式声明但未指定显式 DOP 的表或索引的语句。 具有指定 DOP 的表和索引使用该显式 DOP 设置。
    如果您希望 Oracle 数据库仅为涉及特定对象子集的 SQL 语句子集自动决定 DOP,则将 PARALLEL_DEGREE_POLICY 设置为 LIMITED 并设置并行属性,而不在该对象子集上指定显式 DOP。

  • AUTO
    此设置为所有语句启用 Auto DOP,还启用并行语句排队和内存中并行执行。
    如果您希望 Oracle 数据库自动决定所有 SQL 语句的 DOP,则将 PARALLEL_DEGREE_POLICY 设置为 AUTO。

  • ADAPTIVE
    此设置启用 Auto DOP、并行语句队列和内存中并行执行,类似于 AUTO 值。 此外,还启用了性能反馈。

PARALLEL_DEGREE_LIMIT 初始化参数指定 Auto DOP 可以在系统范围内使用的最大 DOP。要对最大 DOP 进行更细粒度的控制,您可以使用 Oracle Database Resource Manager。

PARALLEL_MIN_TIME_THRESHOLD 初始化参数指定要为 Auto DOP 考虑的语句的最短估计执行时间。首先,优化器计算 SQL 语句的串行执行计划。如果估计的执行时间大于 PARALLEL_MIN_TIME_THRESHOLD 的值,则该语句将成为 Auto DOP 的候选。

PARALLEL_MIN_DEGREE 初始化参数控制由自动并行度计算的最小并行度。但是,如果 PARALLEL_MIN_DEGREE 的值大于 CPU_COUNT 的值或者对象是 Oracle 拥有的,例如字典表或在字典表上创建的视图,则 PARALLEL_MIN_DEGREE 没有影响。

您还可以通过指定适当的语句级或对象级 SQL 提示来请求 Auto DOP。

8.2.6 Adaptive Parallelism

随着系统负载的增加,自适应多用户算法会降低并行度。

使用 Oracle 数据库自适应并行功能时,数据库在 SQL 执行时使用一种算法来确定并行操作是应该接收请求的 DOP 还是降低其 DOP 以确保系统不会过载。

在通过使用高 DOP 积极使用并行执行的系统中,当只有少数操作并行运行时,自适应算法会调低 DOP。虽然该算法仍可确保最佳资源利用率,但用户可能会遇到不一致的响应时间。不建议在需要确定性响应时间的环境中单独使用自适应并行功能。自适应并行性通过数据库初始化参数 PARALLEL_ADAPTIVE_MULTI_USER 控制。

注意:由于初始化参数 PARALLEL_ADAPTIVE_MULTI_USER 在 Oracle Database 12c 第 2 版 (12.2.0.1) 中已弃用并且在未来的版本中将不再支持,因此 Oracle 建议改用并行语句队列。

8.3 In-Memory Parallel Execution

内存中的特性提供了并行执行的技术。

8.3.1 Buffer Cache Usage in Parallel Execution

默认情况下,并行执行不使用 SGA(缓冲区缓存)来缓存扫描的块,除非对象非常小或被声明为 CACHE。

通过将参数 PARALLEL_DEGREE_POLICY 设置为 AUTO 来启用内存中并行执行,使并行语句能够利用 SGA 缓存对象块。 Oracle 数据库决定使用并行执行访问的对象是否会受益于缓存在 SGA 中。缓存对象的决定基于一组明确定义的启发式方法,包括对象的大小和访问它的频率。在 Oracle Real Applications Cluster (Oracle RAC) 环境中,Oracle 数据库将对象的各个部分映射到活动实例上的每个缓冲区缓存中。通过创建此映射,Oracle 数据库自动知道要访问哪个缓冲区缓存以查找对象的不同部分。使用此信息,Oracle 数据库可以防止多个实例一遍又一遍地从磁盘读取相同的信息,从而最大限度地增加可以缓存对象的内存量。它通过在缓存块的实例上使用 PX 服务器来做到这一点。

如果对象的大小大于基于缓冲区缓存(单个实例)总大小或缓冲区缓存大小乘以 Oracle RAC 集群中活动实例数的特定阈值,则该对象为使用直接路径读取而不缓存在 SGA 中。

8.3.2 Automatic Big Table Caching

自动大表缓存将查询与缓冲区缓存集成在一起,以增强 Oracle 数据库在单实例和 Oracle RAC 环境中的内存查询能力。

在 Oracle Real Application Clusters (Oracle RAC) 环境中,仅并行查询支持此功能。 在单实例环境中,并行和串行查询都支持此功能。

为大表缓存保留的缓存部分用于缓存表扫描的数据。 虽然大表缓存主要用于提高数据仓库工作负载的性能,但它也提高了运行混合工作负载的 Oracle 数据库的性能。

自动大表缓存使用​​基于温度和对象的算法来跟踪中型和大型表。 Oracle 确实缓存了非常小的表,但自动大表缓存不会跟踪这些表。

要为串行查询启用自动大表缓存,您必须为 DB_BIG_TABLE_CACHE_PERCENT_TARGET 初始化参数设置一个值(百分比)。此外,您必须将 PARALLEL_DEGREE_POLICY 初始化参数设置为 AUTO 或 ADAPTIVE 以启用并行查询以使用自动大表缓存。在 Oracle RAC 环境中,自动大表缓存仅在并行查询中受支持,因此这两项设置都是必需的。

如果一个大表的大小大约是所有实例的大表缓存的总大小,那么该表在所有实例上都被分区和缓存,或者大部分缓存。内存查询可以消除对表的查询的大多数磁盘读取,或者数据库可以智能地从磁盘中仅读取不适合大表缓存的表部分。如果大表缓存无法缓存所有要扫描的表,则只缓存最频繁访问的表,其余的通过直接读取自动读取。

DB_BIG_TABLE_CACHE_PERCENT_TARGET 参数确定用于扫描的缓冲区高速缓存大小的百分比。 如果 DB_BIG_TABLE_CACHE_PERCENT_TARGET 设置为 80 (%),则缓冲区缓存的 80 (%) 用于扫描,其余 20 (%) 用于 OLTP 工作负载。

仅当 PARALLEL_DEGREE_POLICY 设置为 AUTO 或 ADAPTIVE 时,才在 Oracle RAC 环境中启用 DB_BIG_TABLE_CACHE_PERCENT_TARGET 参数。 DB_BIG_TABLE_CACHE_PERCENT_TARGET 的默认值为 0(禁用),上限为 90 (%),除了表扫描之外,至少保留 10% 的缓冲区缓存供使用。 当值为 0 时,内存中的查询使用现有的最近最少使用 (LRU) 机制运行。 您可以动态调整 DB_BIG_TABLE_CACHE_PERCENT_TARGET 参数。

设置 DB_BIG_TABLE_CACHE_PERCENT_TARGET 参数时,请使用以下准则:

  • 如果在 Oracle RAC 环境中未启用自动并行度 (DOP),则不应设置此参数,因为在这种情况下不使用大表缓存部分。
  • 设置此参数时,应考虑工作负载组合:OLTP 的工作负载有多少; 插入、更新和随机访问; 以及有多少工作负载涉及表扫描。 由于数据仓库工作负载经常执行大表扫描,您可以考虑为大表缓存部分提供更高百分比的数据仓库缓冲区缓存空间。
  • 如果工作负载发生变化,可以动态更改此参数。 根据当前的工作负载,更改可能需要一些时间才能达到目标,因为缓冲区高速缓存内存当时可能正在积极使用。
    当 PARALLEL_DEGREE_POLICY 设置为 AUTO 或 ADAPTIVE 时,会添加数据仓库负载和扫描缓冲区的附加对象级统计信息,以表示对特定(帮助程序)实例上的对象的并行查询 (PQ) 扫描数。

V$BT_SCAN_CACHEV$BT_SCAN_OBJ_TEMPS 视图提供有关大表缓存的信息。

8.4 Parallel Statement Queuing

在某些情况下,并行语句在等待资源时会排队。

当参数 PARALLEL_DEGREE_POLICY 设置为 AUTO 时,如果必要数量的并行执行服务器进程不可用,Oracle 数据库会将需要并行执行的 SQL 语句排队。在必要的资源变得可用后,SQL 语句被出列并被允许执行。默认的出队顺序是一个简单的先进先出队列,基于发出语句的时间。

以下是并行语句处理的概要。

  1. 发出一条 SQL 语句。
  2. 解析语句并自动确定 DOP。
  3. 检查可用的并行资源。
    a. 如果有足够的并行执行服务器可用并且队列中没有等待资源的语句,则执行 SQL 语句。
    b. 如果没有足够的并行执行服务器可用,则 SQL 语句根据指定条件排队,并在满足指定条件时从队列的最前面出列。

如果运行语句会使活动并行服务器的数量增加到超过 PARALLEL_SERVERS_TARGET 初始化参数的值,则并行语句将排队。 例如,如果 PARALLEL_SERVERS_TARGET 设置为 64,当前活动服务器的数量为 60,并且新的并行语句需要 16 个并行服务器,它将排队,因为 16 加到 60 大于 64,即 PARALLEL_SERVERS_TARGET 的值。

该值不是系统上允许的最大并行服务器进程数,而是在使用并行语句排队之前可用于运行并行语句的数量。 它设置为低于系统上允许的最大并行服务器进程数 (PARALLEL_MAX_SERVERS),以确保每个并行语句获得所需的所有并行服务器资源,并防止系统因并行服务器进程而过载。 请注意,即使并行语句队列已被激活,所有串行(非并行)语句也会立即执行。

如果语句已排队,则由 resmgr:pq 排队等待事件标识。

8.4.1 About Managing Parallel Statement Queuing with Oracle Database Resource Manager

默认情况下,并行语句队列作为先进先出队列运行,但您可以使用资源计划修改默认行为。

通过配置和设置资源计划,您可以控制并行语句出列的顺序以及每个工作负载或消费者组使用的并行执行服务器的数量。

Oracle 数据库资源管理器基于消费者组和资源计划的概念运行。 消费者组标识具有相同资源权限和要求的用户组。 资源计划由每个消费者组的指令集合组成,这些指令指定各种数据库资源(例如并行服务器)的控制和分配。 对于多租户容器数据库 (CDB) 和可插拔数据库 (PDB),并行语句队列的顺序由称为 share 的指令管理。

通过将 RESOURCE_MANAGER_PLAN 参数设置为资源计划的名称来启用资源计划。

当并行度策略设置为 AUTO 时,您可以使用以下部分中描述的指令来管理消费者组的并行语句处理。

在所有情况下,给定使用者组的并行语句队列都作为 Oracle RAC 数据库上的单个队列进行管理。 每个使用者组的限制适用于 Oracle RAC 数据库中属于该使用者组的所有会话。 并行语句的排队基于所有数据库实例中 PARALLEL_SERVERS_TARGET 初始化参数的值的总和。

您还可以管理多租户容器数据库 (CDB) 和可插拔数据库 (PDB) 的并行语句队列。

8.4.1.1 About Managing the Order of the Parallel Statement Queue

您可以使用 Oracle 数据库资源管理器来管理从多个使用者组的并行语句队列中出列并行语句的优先级。

默认情况下,特定消费者组的并行语句按 FIFO 顺序出列。 使用指令共享,您可以确定消费者组的并行语句出列的顺序。 您可以使用 DBMS_RESOURCE_MANAGER PL/SQL 包的 CREATE_PLAN_DIRECTIVE 或 UPDATE_PLAN_DIRECTIVE 过程配置这些指令。 您还可以在 CDB 资源计划中设置共享,以管理 PDB 之间并行语句的顺序。

例如,您可以创建 PQ_HIGH、PQ_MEDIUM 和 PQ_LOW 消费者组,并根据优先级将并行语句会话映射到这些消费者组。 然后创建一个资源计划,为 PQ_HIGH 设置 share=14,为 PQ_MEDIUM 设置 share=5,为 PQ_LOW 设置 share=1。 这表明 PQ_HIGH 语句以 70% (14/(14+5+1)=.70) 的概率出队,PQ_MEDIUM 以 25% (5/(14+5+1)= .25) 的时间,PQ_LOW 以 5% (1/(14+5+1)=.05) 的概率出队。

如果并行语句已排队,并且您确定必须立即运行并行语句,则可以运行 DBMS_RESOURCE_MANAGER.DEQUEUE_PARALLEL_STATEMENT PL/SQL 过程以使并行语句出队。

8.4.1.2 About Limiting the Parallel Server Resources for a Consumer Group

您可以使用 Oracle 数据库资源管理器来限制来自较低优先级使用者组的并行语句可用于并行语句处理的并行服务器的数量。

使用 Oracle Database Resource Manager,您可以将并行语句会话映射到不同的使用者组,每个使用者组对可以使用的并行服务器的数量都有特定的限制。 每个消费者组都有自己独立的并行语句队列。 当指定消费者组的这些限制时,来自消费者组的并行语句会在超过其限制时排队。

当数据库具有高优先级和低优先级消费者组时,此限制变得有用。 没有限制,用户可以从使用所有并行服务器的低优先级消费者组发出大量并行语句。 当来自高优先级消费者组的并行语句发出时,资源分配指令可以确保高优先级并行语句首先出列。 通过限制低优先级消费者组可以使用的并行服务器数量,您可以确保始终有一些并行服务器可用于高优先级消费者组。

要限制使用者组使用的并行服务器,请使用带有 CREATE_PLAN_DIRECTIVE 过程的 parallel_server_limit 参数或带有 DBMS_RESOURCE_MANAGER 包中的 UPDATE_PLAN_DIRECTIVE 过程的 new_parallel_server_limit 参数。 parallel_server_limit 参数指定由 PARALLEL_SERVERS_TARGET 指定的消费者组可以使用的 Oracle RAC 范围的并行服务器池的最大百分比。

对于多租户容器数据库 (CDB) 资源计划,并行服务器限制适用于可插拔数据库 (PDB)。 对于 PDB 资源计划或非 CDB 资源计划,此限制适用于使用者组。

例如,在非多租户配置的 Oracle RAC 数据库上,初始化参数 PARALLEL_SERVERS_TARGET 在两个节点上设置为 32,因此在排队开始之前总共可以使用 32 x 2 = 64 个并行服务器。您可以将消费者组 PQ_LOW 设置为使用 50% 的可用并行服务器 (parallel_server_limit = 50),然后可以将低优先级语句映射到 PQ_LOW 消费者组。此方案将 PQ_LOW 使用者组中的任何并行语句限制为 64 x 50% = 32 个并行服务器,即使有更多不活动或未使用的并行服务器。在这种情况下,来自 PQ_LOW 消费者组的语句使用了 32 个并行服务器后,来自该消费者组的语句将排队。

在一个数据库中,可能有一些会话的并行度策略设置为 MANUAL,而一些会话设置为 AUTO。在这种情况下,只有并行度策略设置为 AUTO 的会话才能排队。但是,在并行度策略设置为 MANUAL 的会话中使用的并行服务器包含在消费者组使用的所有并行服务器的总数中。

8.4.1.3 Specifying a Parallel Statement Queue Timeout for Each Consumer Group

您可以使用 Oracle 数据库资源管理器为使用者组设置特定的最大队列超时时间,以便并行语句不会长时间留在队列中。

为了管理队列超时,parallel_queue_timeout 参数与 CREATE_PLAN_DIRECTIVE 过程一起使用,或者 new_parallel_queue_timeout 参数与 DBMS_RESOURCE_MANAGER 包中的 UPDATE_PLAN_DIRECTIVE 过程一起使用。 parallel_queue_timeout 和 new_parallel_queue_timeout 参数指定语句可以保留在使用者组并行语句队列中的时间(以秒为单位)。超时期限到期后,语句要么以错误 ORA-7454 终止,要么从并行语句队列中删除,并根据资源管理器计划中 PQ_TIMEOUT_ACTION 指令的值启用运行。

您可以使用 PQ_TIMEOUT_ACTION 资源管理器指令为并行语句指定队列超时操作。将此指令设置为 CANCEL 会终止语句并返回错误 ORA-7454。将此指令设置为 RUN 可使语句运行。

8.4.1.4 Specifying a Degree of Parallelism Limit for Consumer Groups

您可以使用 Oracle Database Resource Manager 来限制特定使用者组的并行度。

使用 Oracle Database Resource Manager,您可以将并行语句会话映射到不同的使用者组,每个使用者组对资源计划中的并行度都有特定的限制。

要管理使用者组中的并行度限制,请将 parallel_degree_limit_p1 参数与 DBMS_RESOURCE_MANAGER 包中的 CREATE_PLAN_DIRECTIVE 过程一起使用,或者将 new_parallel_degree_limit_p1 参数与 DBMS_RESOURCE_MANAGER 包中的 UPDATE_PLAN_DIRECTIVE 过程一起使用。 parallel_degree_limit_p1 和 new_parallel_degree_limit_p1 参数指定任何操作的并行度限制。

例如,您可以创建 PQ_HIGH、PQ_MEDIUM 和 PQ_LOW 消费者组,并根据优先级将并行语句会话映射到这些消费者组。然后,您创建一个指定并行度限制的资源计划,以便将 PQ_HIGH 限制设置为 16,将 PQ_MEDIUM 限制设置为 8,并将 PQ_LOW 限制设置为 2。

即使 PARALLEL_DEGREE_POLICY 未设置为 AUTO,也会强制执行并行度限制。

8.4.1.5 Critical Parallel Statement Prioritization

PARALLEL_STMT_CRITICAL 参数的设置会影响计划指令中关于并行语句队列的并行语句的关键指定。

  • 如果 PARALLEL_STMT_CRITICAL 参数设置为 QUEUE,则将 PARALLEL_DEGREE_POLICY 设置为 MANUAL 的并行语句将排队。
  • 如果 PARALLEL_STMT_CRITICAL 参数设置为 BYPASS_QUEUE,则并行语句会绕过并行语句队列并立即执行。
  • 如果 PARALLEL_STMT_CRITICAL 设置为 FALSE,则指定默认行为并且没有语句被指定为关键。

因为关键并行语句绕过并行语句队列,系统可能会遇到比 PARALLEL_SERVERS_TARGET 参数指定的更多的活动并行服务器。 在并行服务器数量达到 PARALLEL_MAX_SERVERS 后,允许运行关键并行语句,因此可能会降级一些关键并行语句。

DBA_RSRC_PLAN_DIRECTIVES 视图中的 PARALLEL_STMT_CRITICAL 列指示并行语句是否来自已标记为关键的使用者组。

8.4.1.6 A Sample Scenario for Managing Statements in the Parallel Queue

此场景讨论如何使用使用 Oracle 数据库资源管理器设置的消费者组来管理并行队列中的语句。

对于此场景,请考虑由三种类型的 SQL 语句组成的数据仓库工作负载:

  • 短期 SQL 语句
    短期运行标识运行时间少于一分钟的语句。 您希望这些语句具有非常好的响应时间。
  • 中等运行的 SQL 语句
    中运行表示运行时间超过一分钟但少于 15 分钟的语句。 您希望这些语句具有相当好的响应时间。
  • 长时间运行的 SQL 语句
    长时间运行标识运行时间超过 15 分钟的即席或复杂查询语句。 您预计这些语句需要很长时间。

对于此数据仓库工作负载,您希望短期运行语句的响应时间更短。 为实现这一目标,您必须确保:

  • 长时间运行的语句不会使用所有并行服务器资源,从而迫使较短的语句在并行语句队列中等待。
  • 当短期运行和长期运行的语句都排队时,短期运行的语句应该在长期运行的语句之前出列。
  • 短期查询的 DOP 是有限的,因为非常高的 DOP 的加速不足以证明使用大量并行服务器的合理性。

示例 8-3 显示了如何使用 Oracle 数据库资源管理器设置使用者组,为并行语句队列中的语句设置优先级。 请注意此示例的以下内容:

  • 默认情况下,用户被分配到 OTHER_GROUPS 消费者组。 如果 SQL 语句的估计执行时间超过 1 分钟(60 秒),则用户切换到 MEDIUM_SQL_GROUP。 因为 switch_for_call 设置为 TRUE,所以用户在语句完成后返回到 OTHER_GROUPS。 如果用户在 MEDIUM_SQL_GROUP 并且该语句的估计执行时间长于 15 分钟(900 秒),则用户切换到 LONG_SQL_GROUP。 同样,因为 switch_for_call 设置为 TRUE,所以用户在查询完成后返回到 OTHER_GROUPS。 用于完成切换过程的指令是 switch_time、switch_estimate、switch_for_call 和 switch_group。
  • 在活动并行服务器的数量达到 PARALLEL_SERVERS_TARGET 初始化参数的值后,后续并行语句将排队。 当并行服务器可用时,shares 指令控制并行语句出列的顺序。 因为在本例中 SYS_GROUP 的份额设置为 100%,所以来自 SYS_GROUP 的并行语句总是首先出列。 如果没有来自 SYS_GROUP 的并行语句排队,则来自 OTHER_GROUPS 的并行语句以 70% 的概率出队,以 20% 的概率从 MEDIUM_SQL_GROUP 出队,以 10% 的概率从 LONG_SQL_GROUP 出队。
  • 从 OTHER_GROUPS 发出的并行语句通过 parallel_degree_limit_p1 指令的设置限制为 4 的 DOP。
  • 为了防止 LONG_SQL_GROUP 组的并行语句使用所有并行服务器,这可能会导致来自 OTHER_GROUPS 或 MEDIUM_SQL_GROUP 的并行语句等待很长时间,其 parallel_server_limit 指令设置为 50%。 此设置意味着在 LONG_SQL_GROUP 用完 PARALLEL_SERVERS_TARGET 初始化参数设置的并行服务器的 50% 后,其并行语句被迫在队列中等待。
  • 因为 LONG_SQL_GROUP 组的并行语句可能会排队很长时间,所以超时配置为 14400 秒(4 小时)。 当来自 LONG_SQL_GROUP 的并行语句在队列中等待 4 小时时,该语句将终止并出现错误 ORA-7454。

示例 8-3 使用消费者组在并行语句队列中设置优先级

BEGINDBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();/* Create consumer groups.* By default, users start in OTHER_GROUPS, which is automatically* created for every database.*/DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP('MEDIUM_SQL_GROUP','Medium-running SQL statements, between 1 and 15 minutes.  Medium priority.');DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP('LONG_SQL_GROUP','Long-running SQL statements of over 15 minutes.  Low priority.');/* Create a plan to manage these consumer groups */DBMS_RESOURCE_MANAGER.CREATE_PLAN('REPORTS_PLAN','Plan for daytime that prioritizes short-running queries');DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE('REPORTS_PLAN', 'SYS_GROUP', 'Directive for sys activity',shares => 100);DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE('REPORTS_PLAN', 'OTHER_GROUPS', 'Directive for short-running queries',shares => 70,parallel_degree_limit_p1 => 4,switch_time => 60, switch_estimate => TRUE, switch_for_call => TRUE,switch_group => 'MEDIUM_SQL_GROUP');DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE('REPORTS_PLAN', 'MEDIUM_SQL_GROUP', 'Directive for medium-running queries',shares => 20,parallel_server_limit => 80,switch_time => 900, switch_estimate => TRUE, switch_for_call => TRUE,switch_group => 'LONG_SQL_GROUP');DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE('REPORTS_PLAN', 'LONG_SQL_GROUP', 'Directive for medium-running queries',shares => 10,parallel_server_limit => 50,parallel_queue_timeout => 14400);DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
END;
//* Allow all users to run in these consumer groups */
EXEC DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP('public', 'MEDIUM_SQL_GROUP', FALSE);EXEC DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP('public', 'LONG_SQL_GROUP', FALSE);

8.4.2 Grouping Parallel Statements with BEGIN_SQL_BLOCK END_SQL_BLOCK

通常,由多个并行语句组成的报告或批处理作业尽快完成是很重要的。

例如,当同时启动多个报表时,您可能希望所有报表尽快完成。 但是,您还希望首先完成某些特定报告,而不是同时完成所有报告。

如果报告包含多个并行语句并且 PARALLEL_DEGREE_POLICY 设置为 AUTO,则每个并行语句可能会被迫在繁忙数据库的队列中等待。 例如,以下步骤描述了 SQL 语句处理中的一个场景:

serial statement
parallel query - dop 8-> wait in queue
serial statement
parallel query - dop 32-> wait in queue
parallel query - dop 4-> wait in queue

为了快速完成报告,必须对并行语句进行分组以产生以下行为:

start SQL block
serial statement
parallel query - dop 8-> first parallel query: ok to wait in queue
serial statement
parallel query - dop 32-> avoid or minimize wait
parallel query - dop 4-> avoid or minimize wait
end SQL block

要对并行语句进行分组,可以使用 DBMS_RESOURCE_MANAGER PL/SQL 包中的 BEGIN_SQL_BLOCK 和 END_SQL_BLOCK 过程。 对于每个消费者组,并行语句队列按与每个消费者组的并行语句关联的时间排序。 通常,与并行语句相关的时间是该语句入队的时间,这意味着队列似乎是 FIFO。 当并行语句通过 BEGIN_SQL_BLOCK 和 END_SQL_BLOCK 过程分组到一个 SQL 块中时,第一个排队的并行语句也使用它被排队的时间。 但是,第二个和所有后续并行语句会受到特殊处理,并使用 SQL 块中第一个排队的并行语句的入队时间进行入队。 使用此功能,语句经常移动到并行语句队列的前面。 这种优惠待遇确保他们的等待时间最小化。

8.4.3 About Managing Parallel Statement Queuing with Hints

您可以在 SQL 语句中使用 NO_STATEMENT_QUEUING 和 STATEMENT_QUEUING 提示来影响语句是否与并行语句队列一起排队。

  • NO_STATEMENT_QUEUING
    当 PARALLEL_DEGREE_POLICY 设置为 AUTO 时,此提示允许语句绕过并行语句队列。 但是,绕过语句队列的语句可能会导致系统超过由 PARALLEL_SERVERS_TARGET 初始化参数的值定义的并行执行服务器的最大数量,该参数决定了启动并行语句队列的限制。
    无法保证绕过并行语句队列的语句接收到请求的并行执行服务器的数量,因为只能分配系统上可用的并行执行服务器数量,最多可分配 PARALLEL_MAX_SERVERS 初始化参数的值。

  • STATEMENT_QUEUING
    当 PARALLEL_DEGREE_POLICY 未设置为 AUTO 时,此提示允许将语句考虑用于并行语句排队,但仅当有足够的并行进程可用于在请求的 DOP 处运行时才运行。 在启用排队之前,可用的并行执行服务器的数量等于正在使用的并行执行服务器的数量与系统中允许的最大数量之间的差异,该数量由 PARALLEL_SERVERS_TARGET 初始化参数定义。

8.5 Types of Parallelism

有多种类型的并行。

8.5.1 About Parallel Queries

您可以在 SELECT 语句中使用并行查询和并行子查询,并并行执行 DDL 语句和 DML 语句(INSERT、UPDATE 和 DELETE)的查询部分。按照这里的定义,SELECT不属于DML。

您还可以并行查询外部表。

SQL 查询的并行化决策有两个组成部分:并行化决策和并行度 (DOP)。对于查询、DDL 操作和 DML 操作,这些组件的确定方式不同。为了确定 DOP,Oracle 数据库查看引用对象:

  • 并行查询查看要并行执行的查询部分中的每个表和索引,以确定哪个是引用表。基本规则是选择具有最大 DOP 的表或索引。
  • 对于并行 DML(INSERT、UPDATE、MERGE 和 DELETE),确定 DOP 的引用对象是被插入、更新或删除操作修改的表。并行 DML 还为 DOP 添加了一些限制以防止死锁。如果并行 DML 语句包含子查询,则子查询的 DOP 与 DML 操作的 DOP 相同。
  • 对于并行 DDL,确定 DOP 的参考对象是正在创建、重建、拆分或移动的表、索引或分区。如果并行 DDL 语句包含子查询,则子查询的 DOP 相当于 DDL 操作。

8.5.1.1 Parallel Queries on Index-Organized Tables

索引组织表支持多种并行扫描方法。

这些并行扫描方法包括:

  • 非分区索引组织表的并行快速全扫描
  • 分区索引组织表的并行快速全扫描
  • 分区索引组织表的并行索引范围扫描

您可以将这些扫描方法用于具有溢出区域的索引组织表和包含 LOB 的索引组织表。

8.5.1.2 Nonpartitioned Index-Organized Tables

对非分区索引组织表的并行查询使用并行快速全扫描。

通过将索引段划分为足够多的块范围,然后以需求驱动的方式将块范围分配给并行执行服务器来分配工作。 对应于任何行的溢出块仅由拥有该行的进程以需求驱动的方式访问。

8.5.1.3 Partitioned Index-Organized Tables

索引范围扫描和快速全扫描都可以并行执行。

对于并行快速全扫描,并行化与非分区索引组织表相同。 根据 DOP,每个并行执行服务器会获得一个或多个分区,每个分区都包含主键索引段和关联的溢出段(如果有)。

8.5.1.4 Parallel Queries on Object Types

可以对对象类型表和包含对象类型列的表执行并行查询。

对象类型的并行查询支持可用于对象类型顺序查询的所有功能,包括:

  • 对象类型的方法
  • 对象类型的属性访问
  • 创建对象类型实例的构造函数
  • 对象视图
  • 针对对象类型的 PL/SQL 和 Oracle 调用接口 (OCI) 查询

并行查询的对象类型的大小没有限制。

以下限制适用于对对象类型使用并行查询:

  • 需要一个 MAP 函数来并行执行涉及连接和排序的查询(通过 ORDER BY、GROUP BY 或集合操作)。 如果没有 MAP 函数,查询将自动串行执行。
  • 对象类型不支持并行 DML 和并行 DDL,并且此类语句始终串行执行。

在由于任何这些限制而无法并行执行查询的所有情况下,整个查询将串行执行而不会给出错误消息。

8.5.1.5 Rules for Parallelizing Queries

SQL 查询只能在特定条件下并行执行。

只有满足以下条件之一,才能并行执行 SELECT 语句:

  • 查询包括语句级或对象级并行提示规范(PARALLEL 或 PARALLEL_INDEX)。
  • 查询中引用的模式对象具有与之关联的 PARALLEL 声明。
  • 已启用自动并行度 (Auto DOP)。
  • 使用 ALTER SESSION FORCE PARALLEL QUERY 语句强制并行查询。

此外,执行计划应至少具有以下一项:

  • 全表扫描
  • 跨多个分区的索引范围扫描
  • 索引快速全扫描
  • 并行表函数

8.5.2 About Parallel DDL Statements

8.5.2.1 DDL Statements That Can Be Parallelized

您可以为未分区或分区的表和索引并行执行 DDL 语句。

非分区表和索引的并行 DDL 语句是:

  • CREATE INDEX
  • CREATE TABLE AS SELECT
  • ALTER TABLE MOVE
  • ALTER INDEX REBUILD

分区表和索引的并行 DDL 语句是:

  • CREATE INDEX
  • CREATE TABLE AS SELECT
  • ALTER TABLE {MOVE|SPLIT|COALESCE} PARTITION
  • ALTER INDEX {REBUILD|SPLIT} PARTITION
    • 仅当正在拆分的(全局)索引分区可用时,才能并行执行此语句。

所有这些 DDL 操作都可以在 NOLOGGING 模式下进行并行或串行执行。

索引组织表的 CREATE TABLE 语句可以在有或没有 AS SELECT 子句的情况下并行执行。

并行 DDL 不能发生在具有对象列的表上。 并行 DDL 不能发生在具有 LOB 列的非分区表上。

8.5.2.2 About Using CREATE TABLE AS SELECT in Parallel

并行执行使您可以并行执行查询,并创建从另一个表或表集创建表作为子查询的操作。

这种并行功能在创建汇总表或汇总表时非常有用。

请注意,不能并行创建和填充聚簇表。

图 8-4 说明了从子查询并行创建汇总表。

图 8-4 并行创建汇总表

8.5.2.3 Recoverability and Parallel DDL

并行 DDL 通常用于创建汇总表或执行独立事务的大量数据加载,这些数据并不总是需要可恢复的。

通过关闭 Oracle 数据库日志记录,不会生成撤消或重做日志,因此并行 DML 操作可能会执行得更好,但会变成全有或全无操作。 换句话说,如果操作失败,无论出于何种原因,都必须重做该操作,无法重新启动它。

如果在并行表创建(或任何其他并行 DDL 操作)期间禁用日志记录,则应在创建表后备份包含该表的表空间,以避免由于介质故障导致表丢失。

使用 CREATE TABLE、CREATE INDEX、ALTER TABLE 和 ALTER INDEX 语句的 NOLOGGING 子句来禁用撤消和重做日志生成。

8.5.2.4 Space Management for Parallel DDL

并行创建表或索引具有空间管理含义。

这些空间管理影响会影响并行操作期间所需的存储空间以及创建表或索引后可用的可用空间。

8.5.2.5 Storage Space When Using Dictionary-Managed Tablespaces

当并行创建表或索引时,每个并行执行服务器使用 CREATE 语句的 STORAGE 子句中的值来创建临时段来存储行。

使用 4 MB 的 NEXT 设置和 16 的 PARALLEL DEGREE 创建的表在创建表期间消耗至少 64 兆字节 (MB) 的存储空间,因为每个并行服务器进程以 4 MB 的范围开始。 当并行执行协调器合并段时,可能会修剪一些段,结果表可能小于请求的 64 MB。

8.5.2.6 Free Space and Parallel DDL

当您并行创建索引和表时,每个并行执行服务器都会分配一个新的扩展区并用表或索引数据填充该扩展区。

例如,如果您创建一个 DOP 为 4 的索引,则该索引最初至少有四个扩展区。 对于并行重建索引和并行移动、拆分或重建分区,这种扩展区分配是相同的。

串行操作要求模式对象至少有一个范围。 并行创建要求表或索引至少具有与创建模式对象的并行执行服务器一样多的范围。

当您并行创建表或索引时,可以创建可用空间区域。当并行执行服务器使用的临时段大于存储行所需的段时,就会发生这种情况。

  • 如果每个临时段中的未使用空间大于在表空间级别设置的 MINIMUM EXTENT 参数的值,则 Oracle 数据库在将所有临时段中的行合并到表或索引中时会修剪未使用的空间。未使用的空间返回到系统空闲空间,可以分配给新的extent,但它不能合并成更大的段,因为它不是连续的空间(外部碎片)。
  • 如果每个临时段中的未使用空间小于 MINIMUM EXTENT 参数的值,则在合并临时段中的行时无法修剪未使用空间。这个未使用的空间不归还给系统空闲空间;它成为表或索引的一部分(内部碎片),仅可用于后续插入或需要额外空间的更新。

例如,如果为 CREATE TABLE AS SELECT 语句指定 DOP 为 3,但表空间中只有一个数据文件,则可能会出现内部碎片,如图 8-5 所示。 数据文件的内部表扩展区中的空闲空间区域不能与其他空闲空间合并,也不能作为扩展区分配。

图 8-5 不可用的空闲空间(内部碎片)

8.5.2.7 Rules for DDL Statements

DDL 操作可以在特定条件下并行执行。

只有满足以下条件之一,才能并行执行 DDL 操作:

  • 语法中指定了 PARALLEL 子句(声明)。 对于 CREATE TABLE、CREATE INDEX、ALTER INDEX REBUILD 和 ALTER INDEX REBUILD PARTITION,并行声明存储在数据字典中。
  • 已启用自动并行度 (Auto DOP)。
  • 使用 ALTER SESSION FORCE PARALLEL DDL 语句强制并行 DDL。

8.5.2.8 Rules for CREATE TABLE AS SELECT

CREATE TABLE AS SELECT 语句的 CREATE 操作是根据并行化 DDL 语句的规则进行并行化的。

此外,在语句的 SELECT 部分中指定的语句级 PARALLEL 提示也可以并行化 DDL 操作。

当 CREATE TABLE AS SELECT 的 CREATE 操作被并行化时,Oracle 数据库也会尽可能并行化扫描操作。

即使 DDL 部分没有并行化,SELECT 部分也可以根据并行化查询的规则进行并行化。

自动并行度 (Auto DOP) 并行化 DDL 和语句的查询部分。

8.5.3 About Parallel DML Operations

并行 DML(并行插入、更新、删除和合并)使用并行执行机制来加速或扩展针对大型数据库表和索引的大型 DML 操作。

注意:虽然 DML 通常包括查询,但在本章中,术语 DML 仅指 INSERT、UPDATE、MERGE 和 DELETE 操作。

8.5.3.1 When to Use Parallel DML

并行 DML 在决策支持系统 (DSS) 环境中非常有用,在该环境中,访问大型对象的性能和可伸缩性很重要。 并行 DML 补充了并行查询,为您的 DSS 数据库提供了查询和更新功能。

设置并行性的开销使得并行 DML 操作对于短 OLTP 事务不可行。 但是,并行 DML 操作可以加速在 OLTP 数据库中运行的批处理作业。

使用并行 DML 的几种场景包括:

  • 刷新数据仓库系统中的表
  • 创建中间汇总表
  • 使用评分表
  • 更新历史表
  • 运行批处理作业
8.5.3.1.1 Refreshing Tables in a Data Warehouse System

在数据仓库系统中,必须使用来自生产系统的新数据或修改后的数据定期刷新(更新)大型表。

您可以使用 MERGE 语句有效地执行此操作。

8.5.3.1.2 Creating Intermediate Summary Tables

在 DSS 环境中,许多应用程序需要复杂的计算,包括构建和操作许多大型中间汇总表。

这些汇总表通常是临时的,通常不需要记录。 并行 DML 可以加快对这些大型中间表的操作。 一个好处是您可以将增量结果放入中间表并执行并行更新。

此外,汇总表可能包含累积或比较信息,这些信息必须在应用程序会话之后持续存在; 因此,临时表是不可行的。 并行 DML 操作可以加快对这些大型汇总表的更改。

8.5.3.1.3 Using Scoring Tables

许多 DSS 应用程序会根据一组标准定期对客户进行评分。

分数通常存储在大型 DSS 表中。 然后将分数信息用于做出决定,例如,将其包含在邮件列表中。

此评分活动查询并更新表中的大量行。 并行 DML 可以加快对这些大表的操作。

8.5.3.1.4 Updating Historical Tables

历史表描述了企业在最近时间间隔内的业务交易。

DBA 定期删除一组最旧的行并将一组新行插入到表中。 并行的 INSERT SELECT 和并行的 DELETE 操作可以加速这个翻转任务。

删除分区也可用于删除旧行。 但是,表必须按日期和适当的时间间隔进行分区。

8.5.3.1.5 Running Batch Jobs

在非工作时间在 OLTP 数据库中执行的批处理作业有一个固定的时间,在此期间作业必须完成。 确保及时完成作业的一个好方法是并行执行它们的操作。

随着工作量的增加,可以添加更多的计算机资源; 并行操作的放大特性确保可以满足时间限制。

8.5.3.2 Enable Parallel DML Mode

只有在会话或 SQL 语句中显式启用并行 DML 时,才能并行化 DML 语句。

要在会话中启用此模式,请运行以下 SQL 语句:

ALTER SESSION ENABLE PARALLEL DML;

要在特定 SQL 语句中启用并行 DML 模式,请包含 ENABLE_PARALLEL_DML SQL 提示。 例如:

INSERT /*+ ENABLE_PARALLEL_DML */ …

此模式是必需的,因为并行 DML 和串行 DML 具有不同的锁定、事务和磁盘空间要求,并且默认情况下对会话禁用并行 DML。

禁用并行 DML 时,即使使用了 PARALLEL 提示,也不会并行执行 DML。

在会话中启用并行 DML 时,此会话中的所有 DML 语句都将被视为并行执行。在带有 ENABLE_PARALLEL_DML 提示的 SQL 语句中启用并行 DML 时,仅考虑并行执行该特定语句。但是,即使启用了并行 DML,如果没有并行提示或没有具有并行属性的表,或者违反了并行操作的限制,DML 操作仍然可以串行执行。

会话的 PARALLEL DML 模式不影响 SELECT 语句、DDL 语句和 DML 语句的查询部分的并行性。如果未设置此模​​式,则 DML 操作不会并行化,但 DML 语句中的扫描或连接操作可能仍会并行化。

为会话启用并行 DML 模式后,您可以使用 DISABLE_PARALLEL_DML SQL 提示禁用特定 SQL 语句的模式。

8.5.3.3 Rules for UPDATE, MERGE, and DELETE

更新、合并或删除操作仅在特定条件下并行化。

仅当至少满足以下条件之一时才并行化 UPDATE、MERGE 和 DELETE 操作:

  • 正在更新、合并或删除的表具有由先前的 CREATE TABLE 或 ALTER TABLE 语句设置的 PARALLEL 声明。
  • 在 DML 语句中指定了语句级别或对象级别的 PARALLEL 提示。
  • 已启用自动并行度 (Auto DOP)。
  • 使用 ALTER SESSION FORCE PARALLEL DML 语句强制并行 DML。

如果语句包含子查询或可更新视图,那么它们也可以根据并行化查询的规则并行执行。 并行化 UPDATE、MERGE 和 DELETE 部分的决定独立于查询部分,反之亦然。 语句级 PARALLEL 提示或 Auto DOP 并行化 DML 和查询部分。

8.5.3.4 Rules for INSERT SELECT

插入操作仅在特定条件下并行执行。

仅当至少满足以下条件之一时才并行执行 INSERT 操作:

  • 插入到(引用对象)的表具有由先前的 CREATE TABLE 或 ALTER TABLE 语句设置的 PARALLEL 声明。
  • 在 DML 语句中的 INSERT 之后指定语句级或对象级 PARALLEL 提示。
  • 已启用自动并行度 (Auto DOP)。
  • 使用 ALTER SESSION FORCE PARALLEL DML 语句强制并行 DML。

并行化 INSERT 操作的决定独立于 SELECT 操作,反之亦然。 SELECT 操作可以根据并行化查询的规则进行并行化。 语句级 PARALLEL 提示或 Auto DOP 并行化 INSERT 和 SELECT 操作。

8.5.3.5 Transaction Restrictions for Parallel DML

为了并行执行 DML 操作,并行执行协调器获取并行执行服务器,每个并行执行服务器在自己的并行处理事务下执行一部分工作。

请注意以下条件:

  • 每个并行执行服务器创建一个不同的并行处理事务。
  • 如果您使用回滚段而不是自动撤消管理,您可能希望通过限制驻留在同一回滚段中的并行处理事务的数量来减少回滚段的争用。

协调器也有自己的协调器事务,它可以有自己的回滚段。 为了确保用户级事务的原子性,协调器使用两阶段提交协议来提交由并行进程事务执行的更改。

启用并行 DML 的会话可能会将会话中的事务置于特殊模式:如果事务中的任何 DML 语句并行修改表,则后续串行或并行查询或 DML 语句不能在该事务中再次访问同一个表 . 事务期间看不到并行修改的结果。

尝试访问已在同一事务中并行修改的表的串行或并行语句将被拒绝并显示错误消息。

如果 PL/SQL 过程或块在启用 DML 的并行会话中执行,则此规则适用于过程或块中的语句。

8.5.3.6 Rollback Segments

如果您使用回滚段而不是自动撤消管理,则在使用并行 DML 时会有一些限制。

8.5.3.7 Recovery for Parallel DML

回滚并行 DML 操作所需的时间大致等于执行前向操作所需的时间。

Oracle 数据库支持在事务和进程失败后以及实例和系统失败后进行并行回滚。 Oracle 数据库可以并行化事务恢复的前滚阶段和回滚阶段。

8.5.3.7.1 Transaction Recovery for User-Issued Rollback

由于语句错误导致的事务失败中用户发出的回滚由并行执行协调器和并行执行服务器并行执行。

回滚所用的时间与前向事务大致相同。

8.5.3.7.2 Process Recovery

并行执行协调器或并行执行服务器的故障恢复由PMON 进程执行。

如果并行执行服务器或并行执行协调器失败,则 PMON 回滚该进程的工作,事务中的所有其他进程回滚它们的更改。

8.5.3.7.3 System Recovery

从系统故障中恢复需要重新启动。

恢复由 SMON 进程和由 SMON 产生的任何恢复服务器进程执行。 可以使用并行回滚来恢复并行 DML 语句。 如果初始化参数 COMPATIBLE 设置为 8.1.3 或更高版本,Fast-Start On-Demand Rollback 使终止的事务能够根据需要一次恢复一个块。

8.5.3.8 Space Considerations for Parallel DML

并行更新使用对象中现有的可用空间,而直接路径插入获取数据的新范围。

并行执行与串行执行的空间使用特性可能不同,因为多个并发子事务会修改对象。

8.5.3.9 Restrictions on Parallel DML

有几个适用于并行 DML 的限制。

以下限制适用于并行 DML(包括直接路径 INSERT):

  • UPDATE、MERGE 和 DELETE 操作的分区内并行性要求将 COMPATIBLE 初始化参数设置为 9.2 或更高版本。
  • INSERT VALUES 语句永远不会并行执行。
  • 一个事务可以包含多个修改不同表的并行 DML 语句,但是在一个并行 DML 语句修改一个表之后,后续的串行或并行语句(DML 或查询)不能在该事务中再次访问同一个表。
    • 在串行直接路径 INSERT 语句之后也存在此限制:在该事务期间没有后续 SQL 语句(DML 或查询)可以访问修改后的表。
    • 在并行 DML 或直接路径 INSERT 语句之前允许访问同一个表的查询,但之后不允许。
    • 任何串行或并行语句尝试访问在同一事务期间已被并行 UPDATE、DELETE 或 MERGE 或直接路径 INSERT 修改的表都会被拒绝并显示错误消息。
  • 不能对带有触发器的表执行并行 DML 操作。
  • 并行 DML 不支持复制功能。
  • 并行 DML 不能在存在某些约束的情况下发生:自引用完整性、删除级联和延迟完整性。 此外,对于直接路径 INSERT,不支持任何参照完整性。
  • 如果不访问对象列,则可以对具有对象列的表执行并行 DML。
  • 如果表是分区的,则可以对具有 LOB 列的表执行并行 DML。 但是,不支持分区内并行性。
    对于具有 LOB 列的非分区表,如果将 LOB 列声明为 SecureFiles LOB,则支持并行 INSERT 操作。 不支持对此类表执行并行 UPDATE、DELETE 和 MERGE 操作。
  • 如果 DML 操作在分布式事务中,或者 DML 或查询操作在远程对象上,则它不能并行执行。
  • 不支持聚簇表。
  • 临时表不支持并行 UPDATE、DELETE 和 MERGE 操作。
  • 如果表未分区,则具有位图索引的表不支持并行 DML。

违反这些限制会导致语句在没有警告或错误消息的情况下连续执行(除了限制在事务中访问同一表的语句,这可能会导致错误消息)。

8.5.3.9.1 Partitioning Key Restriction

如果更新不会导致行移动到新分区,则只能将分区表的分区键更新为新值。

如果表是在启用行移动子句的情况下定义的,则可以进行更新。

8.5.3.9.2 Function Restrictions

并行 DML 的功能限制与并行 DDL 和并行查询的功能限制相同。

8.5.3.10 Data Integrity Restrictions

8.5.3.10.1 NOT NULL and CHECK

允许使用 NOT NULL 和 CHECK 完整性约束。 它们对于并行 DML 来说不是问题,因为它们分别在列和行级别上强制执行。

8.5.3.10.2 UNIQUE and PRIMARY KEY

允许 UNIQUE 和 PRIMARY KEY 完整性约束。

8.5.3.10.3 FOREIGN KEY (Referential Integrity)

每当一个表上的 DML 操作可能导致另一个表上的递归 DML 操作时,就会出现对参照完整性的限制。

当执行完整性检查时,这些限制也适用,必须同时查看对正在修改的对象所做的所有更改。

8.5.3.10.4 Delete Cascade

由于并行执行服务器尝试从多个分区(父表和子表)中删除行,因此对具有删除级联外键的表的删除不会并行化。

8.5.3.10.5 Self-Referential Integrity

如果涉及到引用的键(主键),则不会并行化具有自引用完整性约束的表上的 DML。

对于所有其他列上的 DML,并行性是可能的。

8.5.3.10.6 Deferrable Integrity Constraints

如果任何可延迟约束适用于正在操作的表,则不会并行执行 DML 操作。

8.5.3.11 Trigger Restrictions

如果受影响的表包含可能因语句而被调用的启用触发器,则不会并行执行 DML 操作。

这意味着正在复制的表上的 DML 语句不会被并行化。
这句话是什么意思呢?配置了ADG的表可以并行DML吗?
在Oracle Parallel Processing一书中也提到了:

You cannot use parallel DML on tables being replicated.

看来需要测试一下。

必须禁用相关触发器才能在表上并行化 DML。 如果启用或禁用触发器,则相关共享游标将失效。

8.5.3.12 Distributed Transaction Restrictions

如果 DML 操作在分布式事务中,或者 DML 或查询操作在远程对象上,则它不能并行执行。

8.5.3.13 Examples of Distributed Transaction Parallelization

略。

8.5.3.14 Concurrent Execution of Union All

像 UNION 或 UNION ALL 这样的集合运算符由组合到单个 SQL 语句的多个查询(分支)组成。

传统上,集合运算符是按顺序处理的。单个分支可以串行或并行处理,但一次只能处理一个分支,一个接一个分支。虽然这种方法可以满足许多用例,但在某些情况下,应该同时处理 UNION 或 UNION ALL 语句的多个分支。最典型的情况是当几个或所有分支都是远程 SQL 语句时。在这种情况下,希望在所有参与的远程系统上进行并发处理,以加快整体处理时间,而不会增加任何参与系统的工作量。

UNION 或 UNION ALL 语句的并发执行的默认行为由 OPTIMIZER_FEATURES_ENABLE 初始化参数的设置控制。设置为 12.1.0.1 或更高版本时,默认启用并发执行。如果语句的至少一个分支是本地的并被视为并行处理的任何语句,则整个 UNION 或 UNION ALL 语句也将同时处理。系统为语句的每个单独的本地分支计算 DOP,并选择最高的 DOP 来执行整个 UNION 或 UNION ALL 语句。然后系统在尽可能多的分支上同时工作,使用选择的 DOP 来并行处理并行处理的分支,并作为串行和远程语句的并发工作人员。

当 OPTIMIZER_FEATURES_ENABLE 初始化参数设置为小于 12.1.0.1 的值时,必须使用 PQ_CONCURRENT_UNION 提示显式启用 UNION 或 UNION ALL 语句的并发执行。

然而,与一个接一个分支的顺序处理不同,并发处理并不能保证各个分支的结果的有序返回。如果需要一个又一个分支的有序返回,那么您必须使用 NO_PQ_CONCURRENT_UNION 提示禁用并发处理,或者您必须扩充 SQL 语句以唯一标识语句的各个分支并按此指定标识符排序。

除非专门使用 PQ_CONCURRENT_UNION 提示,否则不会同时处理仅包含串行或远程分支的 UNION 或 UNION ALL 语句。该 SQL 语句的 DOP 最多是串行和远程输入的数量。

通过 SQL 语句的执行计划可以很容易地识别出 UNION 或 UNION ALL 语句是否并发处理。当并行执行时,串行和远程分支的执行由可识别为 PX SELECTOR 的行源管理。未同时处理的语句将查询协调器 (QC) 显示为串行和远程分支的协调器。

在示例 8-4 中,SQL 语句由本地和远程分支组成。 SQL 语句从本地数据库加载黄金和白金客户的信息,从远程数据库加载三个主要城市的客户信息。 因为本地选择语句是并行发生的,所以这个处理是自动并行执行的。 每个串行分支仅由一个并行执行服务器进程执行。 因为每个并行执行服务器可以执行一个串行分支,所以它们是并发执行的。

示例 8-4 解释 UNION ALL 的计划

SQL> EXPLAIN PLAN FOR INSERT INTO all_customer SELECT * FROM GOLD_customer UNION ALL SELECT * FROM PLATINUM_customer UNION ALL SELECT * FROM SF_customer@san_francisco UNION ALL SELECT * FROM LA_customer@los_angeles UNION ALL SELECT * FROM LV_customer@las_vegas;
-------------------------------------------------------------------------------
| Id | Operation              | Name          | TQ/Ins |IN-OUT | PQ Distrib|
-------------------------------------------------------------------------------
| 0 | INSERT STATEMENT         |              |        |       |           |
| 1 |  LOAD TABLE CONVENTIONAL | ALL_CUSTOMER |        |       |           |
| 2 |   PX COORDINATOR         |              |        |       |           |
| 3 |    PX SEND QC (RANDOM)   | :TQ10003     |        | P->S  | QC (RAND) |
| 4 |     UNION-ALL            |              |        | PCWP  |           |
| 5 |      PX BLOCK ITERATOR   |              |        | PCWC  |           |
| 6 |       TABLE ACCESS FULL  | GOLD_CUSTOMER|        | PCWP  |           |
| 7 |      PX BLOCK ITERATOR   |              |        | PCWC  |           |
| 8 |       TABLE ACCESS FULL  | PLATINUM_CUST|        | PCWP  |           |
| 9 |      PX SELECTOR         |              |        | PCWP  |           |
|10 |       REMOTE             | SF_CUSTOMER  |        | PCWP  |           |
|11 |      PX SELECTOR         |              |        | PCWP  |           |
|12 |       REMOTE             | LA_CUSTOMER  |        | PCWP  |           |
|13 |      PX SELECTOR         |              |        | PCWP  |           |
|14 |       REMOTE             | LV_CUSTOMER  |        | PCWP  |           |
-------------------------------------------------------------------------------

8.5.4 About Parallel Execution of Functions

SQL 语句可以包含用 PL/SQL、Java 或 C 语言编写的用户定义函数,这些函数可以作为 SELECT 列表、SET 子句或 WHERE 子句的一部分出现。

当 SQL 语句被并行化时,这些函数由并行执行服务器进程逐行执行。 该函数使用的任何 PL/SQL 包变量或 Java 静态属性对每个单独的并行执行过程都是完全私有的,并且在处理每一行时都重新初始化,而不是从原始会话中复制。 由于这个过程,如果并行执行,并非所有函数都会产生正确的结果。

用户编写的表函数可以出现在语句的 FROM 列表中。 这些函数的作用类似于源表,因为它们产生行输出。 表函数在每个并行执行过程开始时的语句期间初始化一次。 所有变量对于并行执行过程都是完全私有的。

8.5.4.1 Functions in Parallel Queries

用户函数可以在 SQL 查询语句中并行执行,也可以在 DML 或 DDL 语句中并行执行。

在 SELECT 语句或 DML 或 DDL 语句中的子查询中,用户编写的函数可以在以下任何情况下并行执行:

  • 如果已使用 PARALLEL_ENABLE 关键字声明
  • 如果它在包或类型中声明并具有指示所有 WNDS、RNPS 和 WNPS 的 PRAGMA RESTRICT_REFERENCES 子句
  • 如果使用 CREATE FUNCTION 声明,系统可以分析 PL/SQL 代码的主体,确定代码既不写入数据库,也不读取或修改包变量

即使给定的函数执行必须保持串行,查询或子查询的其他部分有时也可以并行执行。

8.5.4.2 Functions in Parallel DML and DDL Statements

在某些条件下,用户函数可以在并行 DML 或 DDL 语句中执行。

在并行 DML 或 DDL 语句中,与在并行查询中一样,用户编写的函数可以在以下任何情况下并行执行:

  • 如果已使用 PARALLEL_ENABLE 关键字声明
  • 如果它在包或类型中声明并具有指示所有 RNDS、WNDS、RNPS 和 WNPS 的 PRAGMA RESTRICT_REFERENCES 子句
  • 如果使用 CREATE FUNCTION 语句声明,系统可以分析 PL/SQL 代码的主体,并确定代码既不读取也不写入数据库或读取或修改包变量

对于并行 DML 语句,任何不能并行执行的函数调用都会导致整个 DML 语句串行执行。对于 INSERT SELECT 或 CREATE TABLE AS SELECT 语句,查询部分中的函数调用根据本节中描述的并行查询规则进行并行化。即使语句的其余部分必须串行执行,查询也可以并行化,反之亦然。

8.5.5 About Other Types of Parallelism

Oracle 数据库可以在多种类型的操作中使用并行性。

除了并行 SQL 执行之外,Oracle 数据库还可以将并行性用于以下类型的操作:

  • 并行恢复
  • 并行传播(复制)
  • 并行加载(外部表和 SQL*Loader 实用程序)

与并行 SQL 一样,并行恢复、传播和外部表加载由并行执行协调器和多个并行执行服务器执行。 然而,使用 SQL*Loader 的并行加载使用不同的机制。

并行执行协调器和并行执行服务器的行为可能不同,具体取决于它们执行的操作类型(SQL、恢复或传播)。 例如,如果池中的所有并行执行服务器都被占用,并且已经启动了最大数量的并行执行服务器:

  • 在并行 SQL 和外部表加载中,并行执行协调器切换到串行处理。
  • 在并行传播中,并行执行协调器返回错误。

对于给定的会话,并行执行协调器仅协调一种操作。 并行执行协调器不能同时协调并行 SQL 和并行恢复或传播等。

8.5.6 Degree of Parallelism Rules for SQL Statements

SQL 语句的并行化决策有两个组成部分:并行化决策和并行度 (DOP)。

对于查询、DDL 操作和 DML 操作,这些组件的确定方式不同。

各种类型的 SQL 语句的并行度可以通过语句或对象级 PARALLEL 提示、PARALLEL 子句、ALTER SESSION FORCE PARALLEL 语句、自动并行度 (Auto DOP) 或表或索引 PARALLEL 声明来确定。 当使用这些方法中的一种以上时,Oracle 数据库使用优先规则来确定使用哪种方法来确定 DOP。

表 8-2 显示了确定各种类型 SQL 语句的并行度 (DOP) 的优先级规则。 在表中,较小的优先级数字表示该方法优先于较高的数字。 例如,优先级 (1) 优先于优先级 (2)、优先级 (3)、优先级 (4) 和优先级 (5)。

表 8-2 并行化优先顺序

Parallel 操作 语句级PARALLEL Hint 对象级PARALLEL Hint PARALLEL 子句 ALTER SESSION Auto DOP Parallel声明
Parallel query table/index scan. Priority (1) Priority (2) N/A Priority (3) FORCE PARALLEL QUERY Priority (4) Priority (5)
Parallel UPDATE ,DELETE, or MERGE. Priority (1) Priority (2) N/A Priority (3) FORCE PARALLEL DML Priority (4) 目标表的Priority (5)
并行 INSERT… SELECT 的 INSERT 操作 Priority (1) Priority (2) N/A Priority (3) FORCE PARALLEL DML Priority (4) 插入表的Priority (5)
当 INSERT 为串行时,INSERT SELECT 的 SELECT 操作。 Priority (1) Priority (2) N/A Priority (3) FORCE PARALLEL QUERY Priority (4) SELECT表的Priority (5)
并行 CREATE TABLE AS SELECT 的 CREATE 操作(分区或非分区表) Priority (1) N/A Priority (4) Priority (2) FORCE PARALLEL DDL Priority (3) N/A
CREATE 为串行时 CREATE TABLE AS SELECT 的 SELECT 操作 Priority (1) Priority (2) N/A Priority (3) FORCE PARALLEL QUERY Priority (4) Priority (5)
其他 DDL 操作 N/A N/A Priority (3) Priority (1) FORCE PARALLEL DDL Priority (2) N/A

8.6 About Initializing and Tuning Parameters for Parallel Execution

您可以使用参数来初始化和调整并行执行。

Oracle 数据库根据数据库启动时 CPU_COUNT 和 PARALLEL_THREADS_PER_CPU 的值计算并行执行参数的默认值。 这些参数也可以手动调整,增加或减少它们的值,以适应特定的系统配置或性能目标。 例如,在从不使用并行执行的系统上,PARALLEL_MAX_SERVERS 可以设置为零。

您还可以手动调整并行执行参数。 默认情况下启用并行执行。

8.6.1 Default Parameter Settings

Oracle 数据库默认自动设置并行执行参数。

并行执行参数如表 8-3 所示。

表 8-3 参数及其默认值

参数 默认值 说明
PARALLEL_ADAPTIVE_MULTI_USER FALSE 导致并行执行 SQL 限制并行度 (DOP) 请求以防止系统过载。PARALLEL_ADAPTIVE_MULTI_USER 在 Oracle Database 12c 第 2 版 (12.2.0.1) 中已弃用,将在未来版本中取消支持。 Oracle 建议改用并行语句队列。
PARALLEL_DEGREE_LIMIT CPU 控制使用自动 DOP 时语句可以拥有的最大 DOP。 最大 DOP 为:SUM(CPU_COUNT)*PARALLEL_THREADS_PER_CPU。用于PARALLEL_DEGREE_LIMIT 的 AUTO值 与 CPU值 具有相同的功能。
PARALLEL_DEGREE_POLICY MANUAL 控制是否使用自动 DOP、并行语句队列和内存中并行执行。 默认情况下,所有这些功能都被禁用。
PARALLEL_EXECUTION_MESSAGE_SIZE 16 KB 指定并行执行服务器用于在它们之间以及与查询协调器通信的缓冲区的大小。 这些缓冲区是从共享池中分配的。
PARALLEL_FORCE_LOCAL FALSE 将并行执行限制为当前的 Oracle RAC 实例。
PARALLEL_INSTANCE_GROUP 无。 默认情况下,在所有当前活动的实例中启用并行执行。 允许您将并行查询操作限制为有限数量的实例。 与服务结合使用,也与不推荐使用的参数 INSTANCE_GROUPS 结合使用。
PARALLEL_MAX_ SERVERS 参考这里 指定实例的最大并行执行进程和并行恢复进程数。 随着需求的增加,Oracle 数据库将进程数从实例启动时创建的数量增加到该值。如果将此参数设置得太低,则某些查询在查询处理期间可能没有可用的并行执行过程。 如果设置得太高,在高峰期可能会出现内存资源短缺,从而降低性能。
PARALLEL_MIN_DEGREE 1 控制由自动并行度计算的最小并行度。
PARALLEL_MIN_SERVERS CPU_COUNT * PARALLEL_THREADS_PER_CPU * 2 指定在启动 Oracle 数据库时要启动并为并行操作保留的并行执行进程的数量。 增加此设置可以帮助平衡并行语句的启动成本,但需要更多的内存使用,因为这些并行执行进程在数据库关闭之前不会被删除。
PARALLEL_MIN_PERCENT 0 指定并行执行所需的请求并行执行进程的最小百分比。 使用默认值 0,如果没有可用的并行服务器进程,则并行语句将串行执行。
PARALLEL_MIN_TIME_THRESHOLD AUTO 指定优化器估计的执行时间,超过该时间的语句被视为自动并行查询和 DOP 的自动派生。 请注意,AUTO 的解释取决于是否使用 Database In-Memory。
PARALLEL_SERVERS_TARGET 参考这里 指定在使用并行语句队列之前可用于运行查询的并行执行服务器进程的数量。 请注意,并行语句队列仅在 PARALLEL_DEGREE_POLICY 设置为 AUTO 时才有效。
PARALLEL_THREADS_PER_CPU 1 描述 CPU 在并行执行期间可以处理的并行执行进程或线程的数量。

在Oracle的云服务中,PARALLEL_THREADS_PER_CPU 被设为2。可能是考虑了多线程。

8.6.2 Forcing Parallel Execution for a Session

您可以强制会话的并行性。

如果您确定要并行执行并且希望避免为表设置 DOP 或修改所涉及的查询,则可以使用以下语句强制并行:

ALTER SESSION FORCE PARALLEL QUERY;

只要不违反限制,所有后续查询都将并行执行。 您还可以强制执行 DML 和 DDL 语句。 此子句覆盖会话中后续语句中指定的任何并行子句,但被并行提示覆盖。

例如,在典型的 OLTP 环境中,表未设置为并行,但夜间批处理脚本可能希望从这些表中并行收集数据。 通过在会话中设置 DOP,用户可以避免并行更改每个表,然后在完成后将其更改回串行。

8.6.3 Tuning General Parameters for Parallel Execution

8.6.3.1 Parameters Establishing Resource Limits for Parallel Operations

您可以设置初始化参数来确定资源限制。

8.6.3.1.1 PARALLEL_FORCE_LOCAL

PARALLEL_FORCE_LOCAL 参数指定并行执行的 SQL 语句是否仅限于 Oracle RAC 环境中的单个实例。

通过将此参数设置为 TRUE,您可以将处理的并行服务器的范围限制为运行查询协调器的单个 Oracle RAC 实例。

PARALLEL_FORCE_LOCAL 参数的推荐值为 FALSE。

8.6.3.1.2 PARALLEL_MAX_SERVERS

PARALLEL_MAX_SERVERS 参数指定实例的最大并行执行进程和并行恢复进程数。

随着需求的增加,Oracle 数据库将进程数从实例启动时创建的数量增加到该值。

例如,将值设置为 64 可让您同时运行四个并行查询,如果每个查询使用两个工作集,每个集的 DOP 为 8。

当用户进程过多时

当并发用户的查询服务器进程过多时,可能会发生内存争用(分页)、I/O 争用或过多的上下文切换。

这种争用可以将系统吞吐量降低到比不使用并行执行时更低的水平。 仅当系统有足够的内存和 I/O 带宽来处理结果负载时,才增加 PARALLEL_MAX_SERVERS 值。

您可以使用操作系统的性能监控工具来确定有多少内存、交换空间和 I/O 带宽是空闲的。 查看 CPU 和磁盘的运行队列长度,以及系统上 I/O 操作的服务时间。 验证系统是否有足够的交换空间来添加更多进程。 限制查询服务器进程的总数可能会限制可以执行并行操作的并发用户数量,但系统吞吐量往往保持稳定。

何时限制使用消费者组的用户的资源数量

必要时,您可以通过为用户建立资源使用者组来限制给定用户可用的并行量。

这样做可以限制任何一个用户或用户组可以拥有的会话数、并发登录数和并行进程数。

处理并行执行语句的每个查询服务器进程都使用会话 ID 登录。 每个进程都计入用户的并发会话限制。 例如,要将用户限制为 10 个并行执行进程,请将用户的限制设置为 11。一个进程用于并行执行协调器,另外 10 个进程由两组查询服务器组成。 这将允许并行执行协调器的一个会话和并行执行进程的 10 个会话。

8.6.3.1.3 PARALLEL_MIN_PERCENT

PARALLEL_MIN_PERCENT 参数使用户能够等待可接受的 DOP,具体取决于正在使用的应用程序。

PARALLEL_MIN_PERCENT 参数的推荐值为 0(零)。 将此参数设置为 0(零)以外的值会导致 Oracle 数据库在系统在给定时间无法满足请求的 DOP 时返回错误。 例如,如果您将 PARALLEL_MIN_PERCENT 设置为 50,即 50%,并且由于自适应算法或资源限制,DOP 减少了 50% 或更多,则 Oracle 数据库返回 ORA-12827。 例如:

SELECT /*+ FULL(e) PARALLEL(e, 8) */ d.department_id, SUM(SALARY)FROM employees e, departments d WHERE e.department_id = d.department_idGROUP BY d.department_id ORDER BY d.department_id;

Oracle 数据库响应此消息:

ORA-12827: insufficient parallel query slaves available
8.6.3.1.4 PARALLEL_MIN_SERVERS

PARALLEL_MIN_SERVERS 参数指定要在单个实例中启动的为并行操作保留的进程数。

设置 PARALLEL_MIN_SERVERS 可以平衡启动成本和内存使用量。 使用 PARALLEL_MIN_SERVERS 启动的进程在数据库关闭之前不会退出。 这样,当发出查询时,进程很可能可用。

8.6.3.1.5 PARALLEL_MIN_TIME_THRESHOLD

PARALLEL_MIN_TIME_THRESHOLD 参数指定语句在考虑自动并行度之前应该具有的最短执行时间。

默认是10秒,如果所有表都在IMCS中,则为1秒。

8.6.3.1.6 PARALLEL_SERVERS_TARGET

PARALLEL_DEGREE_POLICY 参数指定在使用语句队列之前允许运行并行语句的并行服务器进程数。

当 PARALLEL_DEGREE_POLICY 设置为 AUTO 时,如果系统上当前使用的并行进程数等于或大于 PARALLEL_SERVERS_TARGET,则需要并行执行的语句将排队。 这不是系统上允许的最大并行服务器进程数(由 PARALLEL_MAX_SERVERS 控制)。 但是,PARALLEL_SERVERS_TARGET 和并行语句队列用于确保为每个需要并行执行的语句分配必要的并行服务器资源,并且系统不会被过多的并行服务器进程淹没。

8.6.3.1.7 SHARED_POOL_SIZE

SHARED_POOL_SIZE 参数指定共享池的内存大小。

除了串行 SQL 执行所需的内存资源外,并行执行还需要内存资源。 额外的内存用于查询服务器进程和查询协调器之间的通信和传递数据。

Oracle 数据库从共享池中为查询服务器进程分配内存。 调整共享池如下:

  • 允许共享池的其他客户端,例如共享游标和存储过程。
  • 请记住,较大的值会提高多用户系统的性能,但较小的值会占用更少的内存。
  • 然后,您可以监视并行执行使用的缓冲区数量,并将共享池 PX msg 池与视图 V$PX_PROCESS_SYSSTAT 的输出中报告的当前高水位线进行比较。

注意:如果您没有足够的可用内存,则会出现错误消息 12853(PX 缓冲区内存不足:当前字符串 K,需要的最大字符串 K)。 这是由于没有足够的 SGA 内存可用于 PX 缓冲区。 您必须将 SGA 重新配置为至少具有 (MAX - CURRENT) 字节的附加内存。

默认情况下,Oracle 数据库从共享池中分配并行执行缓冲区。

如果 Oracle 数据库在启动时显示以下错误,则应将 SHARED_POOL_SIZE 的值减小到足够低,以便数据库启动:

ORA-27102: out of memory
SVR4 Error: 12: Not enough space

减少 SHARED_POOL_SIZE 的值后,您可能会看到以下错误:

ORA-04031: unable to allocate 16084 bytes of shared memory ("SHARED pool","unknown object","SHARED pool heap","PX msg pool")

如果是这样,请执行以下查询以确定 Oracle 数据库无法分配 16,084 字节的原因:

SELECT NAME, SUM(BYTES) FROM V$SGASTAT WHERE UPPER(POOL)='SHARED POOL' GROUP BY ROLLUP (NAME);

您的输出应类似于以下内容:

NAME                       SUM(BYTES)
-------------------------- ----------
PX msg pool                   1474572
free memory                    5621322036704

如果您指定 SHARED_POOL_SIZE 并且您指定要保留的内存量大于池,则 Oracle 数据库不会分配它可以获得的所有内存。 相反,它留下了一些空间。 当查询运行时,Oracle 数据库会尝试获取它需要的内容。 Oracle 数据库使用 560 KB,失败时还需要 16 KB。 该错误不会报告所需的累积金额。 确定需要多少内存的最佳方法是使用消息缓冲区的附加内存要求中的公式。

要解决当前示例中的问题,请增加 SHARED_POOL_SIZE 的值。 如示例输出所示,SHARED_POOL_SIZE 约为 2 MB。 根据可用内存量,您可以将 SHARED_POOL_SIZE 的值增加到 4 MB 并尝试启动数据库。 如果 Oracle 数据库继续显示 ORA-4031 消息,请逐渐增加 SHARED_POOL_SIZE 的值,直到启动成功。

8.6.3.1.8 Additional Memory Requirements for Message Buffers

确定共享池的初始设置后,必须计算消息缓冲区的额外内存需求并确定游标需要多少额外空间。

消息缓冲区所需的内存

您必须增加 SHARED_POOL_SIZE 参数的值以适应消息缓冲区。 消息缓冲区允许查询服务器进程相互通信。

Oracle 数据库为生产者查询服务器和消费者查询服务器之间的每个虚拟连接使用固定数量的缓冲区。 连接随着 DOP 的平方增加而增加。 因此,并行执行使用的最大内存量受系统允许的最高 DOP 的约束。 您可以使用 PARALLEL_MAX_SERVERS 参数或使用策略和配置文件来控制此值。

要计算所需的内存量,请使用以下公式之一:

对于 SMP 系统:

mem in bytes = (3 x size x users x groups x connections)

Oracle Real Application Clusters and MPP 系统:

mem in bytes = ((3 x local) + (2 x remote)) x (size x users x groups) / instances

每个实例使用公式计算的内存。

术语是:

  • SIZE = PARALLEL_EXECUTION_MESSAGE_SIZE

  • USERS = 您希望以最佳 DOP 运行的并发并行执行用户数

  • GROUPS = 用于每个查询的查询服务器进程组的数量
    一个简单的 SQL 语句只需要一组。但是,如果您的查询涉及并行处理的子查询,那么 Oracle 数据库将使用一组额外的查询服务器进程。

  • CONNECTIONS = (DOP2 + 2 x DOP)
    如果您的系统是集群或 MPP,那么您应该考虑实例的数量,因为这会增加 DOP。换句话说,在两个实例集群上使用 4 的 DOP 会导致 8 的 DOP。PARALLEL_MAX_SERVERS 乘以实例数除以 4 的值是用作起点的保守估计。

  • LOCAL = CONNECTIONS/INSTANCES

  • REMOTE = CONNECTIONS - LOCAL

将此结果添加到共享池的原始设置中。但是,在为这些内存结构中的任何一个设置值之前,您还必须考虑为游标增加内存,如下节所述。

Cursors的额外内存

并行执行计划比串行执行计划消耗更多的 SQL 区域空间。 您应该定期监视共享池资源的使用情况,以确保消息和游标使用的内存能够满足您系统的处理要求。

8.6.3.1.9 Monitor Memory Usage After Processing Begins

无论您是使用自动调优还是手动调优,您都应该持续监控使用情况,以确保内存大小不会太大或太小。

本节中的公式只是起点。 要确保正确的内存大小,请使用以下查询调整共享池:

SELECT POOL, NAME, SUM(BYTES) FROM V$SGASTAT WHERE POOL LIKE '%pool%'GROUP BY ROLLUP (POOL, NAME);

您的输出应类似于以下内容:

POOL           NAME                       SUM(BYTES)
-------------- -------------------------- ----------
shared pool    kghpinfo min lru                  176
shared pool    Reset Parameter Handle fo         248
shared pool    kspcmhdl                        12248
shared pool    kghx free lists                 12312
shared pool    KESTB existence bitvec         262144
shared pool    kzxssuf heap                      160
shared pool    KGLS                         12257376
shared pool    615.kggec                        9072
shared pool    ksfdsspdbnfy1                     128
shared pool    KCB tablespace encryption        1320
shared pool    AWR Flushing Error Contro          80
shared pool    KTT File Space Usage (PDB        2184
shared pool    ksupd proc death                   24
shared pool    KKSSP                           67808
shared pool    KTU latches                      1320
shared pool    KKKI consumer                    5416
shared pool    Result Cache: Bloom Filte        8192
shared pool    SAGE commit cache node Al       22528
shared pool    SWRF Metric TMM Table              72
shared pool    KEBM SGA struct - PDB Ent          16
shared pool    sot->data_kdliso                  192
shared pool    kdmfssgaheap                      136
shared pool    PDBHP                          852416
shared pool    IMCDT Mgmt                       4016
shared pool    Session Template                   96
shared pool    system default language h         568
shared pool    kkcnRstatIni                     3248
shared pool    KTU lat struct                   1760
shared pool    Result Cache: Cache MgrS         1608
shared pool    htab_keiutsg                      512
shared pool    kodosgi kodos                      32
shared pool    SWRF Metric Global SGA          11112
shared pool    Array of TopN Table delta          16
shared pool    KEWR Table Catalog in PDB       20744
shared pool    parameter blocks                47976
shared pool    KTU Recovery SGA                   64
shared pool    change notification obj m       16416
shared pool    session template cache bu       28672
shared pool    session template spare ta       11056
shared pool    SAGE commit cache Allocat         176
shared pool    session template spare de       12456
shared pool    KQR X SO                      5886352
shared pool    rules engine context              200
shared pool    database creation languag        1136
shared pool    kskpdbmetric                      336
shared pool    KEW PDB SGA Structure             104
shared pool    PRTDS                          748240
shared pool    sot                               144
shared pool    KTUR HIST INFO                   4840
shared pool    KGLHBPVEC                     2675880
shared pool    parameter handle                12256
shared pool    ksr message pool free que       10560
shared pool    IM segment gdh_metadata            16
shared pool    kdmgdfreeHTqueue                 4112
shared pool    kponPdbNfy: alo eshdinfo            8
shared pool    latch descriptor state           1920
shared pool    KTCNQROW colnames                5504
shared pool    KTCN queries hash table           128
shared pool    KKTDF                           12272
shared pool    kghpinfo bathdr                    24
shared pool    kdlwss                            840
streams pool   fixed allocation callback         448
streams pool   spilled:kwqblspm                  256
shared pool    KGLNA                           27208
shared pool    kesutlRecHeapAlloc:desc           160
shared pool    KTCNQROW colname ptrs             344
shared pool    KTCN: Obj Invalidation Se       34056
shared pool    kdmfsdwrheap                      136
shared pool    zasasga                            16
shared pool    alls-ktimcem                  1048824
shared pool    Result Cache: Latch Mgr          1032
shared pool    session template attr idx       24696
shared pool    krvxfda-dka                      1088
shared pool    KESATSC SGA Structure             256
shared pool    temporary tabl                 603936
shared pool    kponPdbNfy: alo einfo              72
shared pool    mixed PDB latch                   480
shared pool    Role(ud) graph heap               160
shared pool    pdb latch table                  9240
shared pool    2383.kgght                       3984
shared pool    dso->mds_kdlidso                 1152
shared pool    kcbi io desc                     8608
shared pool    kskpdbstats                    523264
shared pool    free memory                 402777000
shared pool    KEWS PDB System Stat valu         192
shared pool    KEWR PDB SGA - UMF MDB En        2288
shared pool    PDB stats array                 12656
shared pool    zlllab Group Tree Heap De         160
shared pool    kkaenc                           1408
shared pool    KTCN: Hash Table Segmente        9064
streams pool   kwqbsinfy:bqgctx                 1824
shared pool    SWRF Metric RBSM struct          4896
shared pool    Auto tune undo info                96
shared pool    TG subheap descriptor             136
shared pool    global container timeout         2048
shared pool    Result Cache: History Mgr        1856
shared pool    PRTMV                         2233296
shared pool    kwrsnfy: kwrsoe                  8096
shared pool    pdb event stats                 16392
shared pool    ktg hash buckets                13576
shared pool    latch where stats               22368
shared pool    KTCNC inv ht                      128
shared pool    SWRF Metric DRM Table            1664
shared pool    Service-level (PDB) setti        8552
shared pool    KSK PDB IO stat per pdb           360
shared pool    Reset Parameter Blocks fo       47976
shared pool    KKBTD                            3712
shared pool    ksusessnetstat                  96768
shared pool    KTCN global operators              64
shared pool    kpscad: kpscscon                  552
shared pool    ClientID (PDB) trace sett        7784
large pool     kdfibufferslp              2202009600
shared pool    TG shared direct path inf         104
shared pool    SQLP                           622384
shared pool    qesrcSet_Init                   24536
shared pool    PLMCD                          109856
shared pool    kdCStat hash table            1048576
shared pool    ksupd SQL Context                1120
shared pool    ktgCircBuf:MinActScn Trc        40032
shared pool    PLDIA                         1804112
shared pool    KGLDA                        11646888
shared pool    KTCN global operands ht           128
shared pool    ksupdbstaen_ent_tab                 8
shared pool    KGI Session State                  40
shared pool    kodosgi kopfdo                    416
shared pool    KTCN: query inv Segmented        7752
shared pool    sort segment handle              4208
shared pool    ksupd latch recovery              168
shared pool    KQR X PO                      5346816
shared pool    KOKTD                         1187472
shared pool    KTU PDB dynamic SGA local          40
shared pool    qesrcMM_Init:0                   1472
shared pool    local undo segment bit ve        4096
shared pool    KKTSR                           25984
shared pool    UNDO INFO HASH                  43072
shared pool    joxs struct                       608
shared pool    TEMP UNDO STAT INFO             41472
shared pool    INSTANCE INFO                      56
java pool      free memory                  67108864
streams pool   kwqbsinfy:statslx                 768
streams pool   image handles:kwqbsinfy           576
streams pool   kgqmdm_fl_1                       336
shared pool    pdb latch bitmap                  152
shared pool    Securefile fast space usa        1176
shared pool    qksbgCreateSystemEnv: qks         256
shared pool    16592.kggec                      4896
shared pool    KEWS PDB SGA                        8
shared pool    350.kgght                        5088
shared pool    Result Cache                  8738152
shared pool    ksupd List head                    24
shared pool    ktcncchildlatch                  7424
shared pool    kecuNotifier: alloc subhe         160
shared pool    ksfd: consumer group i/o         4256
shared pool    PDB exp set list                  752
shared pool    parameter text value              272
shared pool    Label Cache Heap descrptr         160
shared pool    pdb latch where stats           85456
shared pool    kghifx descriptors                224
shared pool    UNDO STAT INFO                  59904
shared pool    kdmfsdwlheap                      136
shared pool    Client ID (PDB) trace set         536
shared pool    Autotask Error Control in          80
shared pool    Session Template Block             48
shared pool    KTCN: Row Change Segmente       38376
shared pool    SQLA                        650389272
shared pool    KEWR AWR table catalog             32
shared pool    ksupdbstaen_hdl_tab                 8
shared pool    PDB Autotask SGA                  808
shared pool    kcbi io desc slot             1314816
shared pool    qksceAllocateSga:ce              1192
shared pool    SWRF Metric ksuTimebuf           1344
shared pool    SWRF Metric RRM Table            1152
shared pool    affs-ktimcem                    16384
large pool     free memory                 273285120
streams pool   kwqbsinfy:cco                    1056
shared pool    KTU latch cleanup                2496
shared pool    zafwctx                        182704
shared pool    Role(rs) graph heap               160
shared pool    alls-ktsimcsgtinfo             221432
shared pool    TG subheap des                  34136
shared pool    mixed PDB latch descripto         192
shared pool    XCT SGA                             8
shared pool    ktilm hash table              1048576
shared pool    Key Management heap               160
shared pool    parameter value memory           2352
shared pool    kskpdbopennfy                   17392
shared pool    kskcgmetric                      6048
shared pool    UNDO INFO SEGMENTED ARRAY      246240
shared pool    KKTIN                           10232
shared pool    Policy Cache Heap descrpt         160
shared pool    kghpinfo freelist                  80
shared pool    joxs heap                        4960
shared pool    Session Template Base Att      148152
shared pool    kzxiIniSGA:Late binding D         448
shared pool    kupvj alloc                      5080
shared pool    PDB inst stats array             5368
shared pool    ktfa dynamic SGA allocati         632
shared pool    KESTB existence bitvec se        2048
streams pool   kwqbsinfy:bmsg                    512
streams pool   kwqbsinfy:mprop                  2944
shared pool    KCB buffer wait statistic         232
shared pool    change notification regis       16416
shared pool    Service level (PDB) trace         536
shared pool    ksxmsg_htab                      8192
shared pool    KEUM PDB SGA Structure              8
shared pool    KSK Redo session info             400
shared pool    KGLH0                       135785448
shared pool    ksp master psta                  1560
shared pool    fixed allocation callback          24
shared pool    Role(rg) graph heap               160
shared pool    KJGCR pdb data                     24
shared pool    kupva alloc                      1200
shared pool    Result Cache: Cache Mgr          7360
shared pool    SWRF Metric WCTimebuf            1344
shared pool    KGLHD                        19579936
shared pool    MinActScn Array                   320
shared pool    dso->iods_kdlidso                 776
shared pool    KTM PDB dynamic SGA local          56
shared pool    SWRF Metric CHBs               245608
shared pool    kzsc:kzscstob_co                12288
shared pool    kzsc:kzscstob                     144
shared pool    Result Cache: Memory Mgr          832
shared pool    SQLK                            52624
shared pool    session template new list        2944
shared pool    qmkmProtocol:qmdpsg              1600
shared pool    Policy Cache H                  13424
shared pool    KTCN global clauses  ht           128
shared pool    parameter table block           48024
shared pool    pdb event stats segment s          32
shared pool    kwspnfy-pdb                       120
shared pool    global container context          160
shared pool    UNDO INFO                          16
shared pool    Result Cache: Child Latch        1280
shared pool    SWRF Metric Eidbuf              73616
shared pool    kcbi memory desc                 3312
shared pool    pdb event stats segment        201600
shared pool    KTU avail cache                  4032
streams pool   free memory                 133541744
shared pool                               1271241560
streams pool                               133550464
large pool                                2475294720
java pool                                   671088643947195608243 rows selected.

如您的输出所示评估使用的内存,并根据您的处理需要更改 SHARED_POOL_SIZE 的设置。

要获取更多内存使用统计信息,请执行以下查询:

SELECT * FROM V$PX_PROCESS_SYSSTAT WHERE STATISTIC LIKE 'Buffers%';

您的输出应类似于以下内容:

STATISTIC                                     VALUE     CON_ID
---------------------------------------- ---------- ----------
Buffers Allocated                            281506          0
Buffers Freed                                281506          0
Buffers Current                                   0          0
Buffers HWM                                     148          0

使用的内存量显示在 Buffers Current 和 Buffers HWM 统计信息中。 通过将缓冲区数乘以 PARALLEL_EXECUTION_MESSAGE_SIZE 的值来计算以字节为单位的值。 将高水位标记与并行执行消息池大小进行比较,以确定您是否分配了过多的内存。 例如,在第一个输出中,px msg pool 中显示的 large pool 的值为 38,092,812 或 38 MB。 第二个输出的 Buffers HWM 为 3,620,乘以并行执行消息大小 4,096 为 14,827,520,或大约 15 MB。 在这种情况下,高水位线已达到其容量的大约 40%。

8.6.3.2 Parameters Affecting Resource Consumption

注意:在考虑以下部分之前,您应该阅读 MEMORY_TARGET 和 MEMORY_MAX_TARGET 初始化参数的说明以了解详细信息。 PGA_AGGREGATE_TARGET 初始化参数不需要像MEMORY_TARGET那样设置以 自动调整 SGA 和 PGA 组件。

本节讨论的第一组参数影响所有并行操作的内存和资源消耗,特别是并行执行。 这些参数是:

  • PGA_AGGREGATE_TARGET
  • PARALLEL_EXECUTION_MESSAGE_SIZE

第2组参数参见8.6.3.2.3小节。

要控制资源消耗,您应该在两个级别上配置内存:

  • 在数据库级别,因此系统使用来自操作系统的适当数量的内存。
  • 在操作系统级别保持一致性。
    在某些平台上,您可能需要设置操作系统参数来控制可用虚拟内存的总量,即所有进程的总和。

数据仓库操作中使用的大部分内存(与 OLTP 相比)更具动态性。 这块内存来自进程全局区(PGA),进程内存的大小和进程的数量都可以有很大的不同。 在这种情况下,使用 PGA_AGGREGATE_TARGET 初始化参数来控制进程内存和进程数。 显式设置 PGA_AGGREGATE_TARGET 和 MEMORY_TARGET 可确保自动调整仍然发生,但 PGA_AGGREGATE_TARGET 不会调整到低于指定值。

8.6.3.2.1 PGA_AGGREGATE_TARGET

您可以通过设置初始化参数(例如 PGA_AGGREGATE_TARGET)来启用自动 PGA 内存管理。

您可以通过启用自动 PGA 内存管理来简化和改进 PGA 内存的分配方式。 在这种模式下,Oracle 数据库根据 DBA 明确设置的总体 PGA 内存目标动态调整专用于工作区的 PGA 内存部分的大小。 要启用自动 PGA 内存管理,您必须设置初始化参数 PGA_AGGREGATE_TARGET。 对于新安装,PGA_AGGREGATE_TARGET 和 SGA_TARGET 由数据库配置助手 (DBCA) 自动设置,MEMORY_TARGET 为零。 也就是说,自动内存管理被禁用。 因此,默认情况下会启用聚合 PGA 的自动调整。 但是,除非您通过将 MEMORY_TARGET 设置为非零值来启用自动内存管理,否则聚合 PGA 不会增长。

8.6.3.2.1.1 HASH_AREA_SIZE

HASH_AREA_SIZE 已被弃用,您应该改用 PGA_AGGREGATE_TARGET。

8.6.3.2.1.2 SORT_AREA_SIZE

SORT_AREA_SIZE 已被弃用,您应该改用 PGA_AGGREGATE_TARGET。

8.6.3.2.2 PARALLEL_EXECUTION_MESSAGE_SIZE

PARALLEL_EXECUTION_MESSAGE_SIZE 参数指定用于并行执行消息的缓冲区大小。

PARALLEL_EXECUTION_MESSAGE_SIZE 的默认值是特定于操作系统的,但通常为 16 K。该值对于大多数应用程序来说应该足够了。

8.6.3.2.3 Parameters Affecting Resource Consumption for Parallel DML and Parallel DDL

本主题介绍了影响并行 DML 和并行 DDL 操作的资源消耗的参数。

影响并行 DML 和并行 DDL 资源消耗的参数有:

  • TRANSACTIONS
  • FAST_START_PARALLEL_ROLLBACK
  • DML_LOCKS

并行插入、更新和删除操作比串行 DML 操作需要更多资源。 同样,PARALLEL CREATE TABLE AS SELECT 和 PARALLEL CREATE INDEX 可能需要更多资源。 因此,您可能需要增加几个附加初始化参数的值。 这些参数不会影响查询的资源。

8.6.3.2.3.1 TRANSACTIONS

TRANSACTIONS 参数影响并行 DML 和 DDL 下的事务数。

对于并行 DML 和 DDL,每个查询服务器进程都会启动一个事务。 并行执行协调器使用两阶段提交协议提交事务; 因此,DOP 处理的交易数量会增加。 因此,您可能需要增加 TRANSACTIONS 初始化参数的值。

TRANSACTIONS 参数指定最大并发事务数。 TRANSACTIONS 的默认值假定没有并行性。 例如,如果您的 DOP 为 20,则您还有 20 个新服务器事务(或 40,如果您有两个服务器集)和 1 个协调器事务。 在这种情况下,如果事务在同一实例中运行,则应将 TRANSACTIONS 增加 21(或 41)。 如果不设置此参数,Oracle 数据库会将其设置为等于 1.1 x SESSIONS 的值。 如果您使用服务器管理的撤消,则此讨论不适用。

8.6.3.2.3.2 FAST_START_PARALLEL_ROLLBACK

如果系统在存在未提交的并行 DML 或 DDL 事务时出现故障,您可以使用 FAST_START_PARALLEL_ROLLBACK 参数在启动期间加快事务恢复。

FAST_START_PARALLEL_ROLLBACK 参数控制恢复终止事务时使用的 DOP。 终止事务是在系统故障之前处于活动状态的事务。 默认情况下,选择的 DOP 最多为 CPU_COUNT 参数值的两倍。

如果默认 DOP 不足,请将该参数设置为 HIGH。 这给出的最大 DOP 最多为 CPU_COUNT 参数值的四倍。 此功能默认可用。

8.6.3.2.3.3 DML_LOCKS

应设置 DML_LOCKS 参数以说明并行 DML 操作持有的锁数。

DML_LOCKS 参数指定 DML 锁的最大数量。 它的值应该等于所有用户引用的所有表上的锁总数。 并行 DML 操作的锁定要求与串行 DML 非常不同。 并行 DML 持有更多锁,因此您应该将 DML_LOCKS 参数的值增加等量。

注意:当目标表的表锁被禁用时,不会执行并行 DML 操作。

表 8-4 显示了协调器和并行执行服务器进程为不同类型的并行 DML 语句获取的锁类型。 使用此信息,您可以确定这些参数所需的值。

表 8-4 并行 DML 语句获取的锁

语句类型 协调进程需要 每一个并行执行服务器需要
并行 UPDATE 或 DELETE 到分区表; WHERE 子句修剪为分区或子分区的子集 1 table lock SX
1 partition lock X for each pruned partition or subpartition
1 table lock SX
1 partition lock NULL for each pruned partition or subpartition owned by the query server process
1 partition-wait lock S for each pruned partition or subpartition owned by the query server process
并行行迁移 UPDATE 到分区表; WHERE 子句修剪为分区或子分区的子集 1 table lock SX
1 partition X lock for each pruned partition or subpartition
1 partition lock SX for all other partitions or subpartitions
1 table lock SX
1 partition lock NULL for each pruned partition or subpartition owned by the query server process
1 partition-wait lock S for each pruned partition owned by the query server process
1 partition lock SX for all other partitions or subpartitions
并行 UPDATE、MERGE、DELETE 或 INSERT 到分区表 1 table lock SX
Partition locks X for all partitions or subpartitions
1 table lock SX
1 partition lock NULL for each partition or subpartition
1 partition-wait lock S for each partition or subpartition
并行插入到分区表中; 带有分区或子分区子句的目标表 1 table lock SX;
1 partition lock X for each specified partition or subpartition
1 table lock SX
1 partition lock NULL for each specified partition or subpartition
1 partition-wait lock S for each specified partition or subpartition
并行插入到非分区表中 1 table lock X None

注意:表、分区和分区等待 DML 锁在 V$LOCK 视图中都显示为 TM 锁。

考虑一个具有 600 个分区且 DOP 为 100 的表。假设所有分区都包含在没有行迁移的并行 UPDATE 或 DELETE 语句中。

协调员获得:

  • 1个表锁SX
  • 600个分区锁X

总服务器进程获取:

  • 100 个表锁 SX
  • 600 个分区锁 NULL
  • 600 个分区等待锁 S

8.6.3.3 Parameters Related to I/O

影响 I/O 的参数有:

  • DB_CACHE_SIZE
  • DB_BLOCK_SIZE
  • DB_FILE_MULTIBLOCK_READ_COUNT
  • DISK_ASYNCH_IO 和 TAPE_ASYNCH_IO

这些参数也会影响优化器,从而确保并行执行 I/O 操作的最佳性能。

8.6.3.3.1 DB_CACHE_SIZE

DB_CACHE_SIZE 参数为具有主块大小的缓冲区设置默认缓冲池的大小。

当您执行并行更新、合并和删除操作时,缓冲区缓存行为与运行大量更新的任何 OLTP 系统非常相似。

8.6.3.3.2 DB_BLOCK_SIZE

DB_BLOCK_SIZE 参数设置 Oracle 数据库块的大小。

此参数的推荐值为 8 KB 或 16 KB。

创建数据库时设置数据库块大小。 如果要创建新数据库,请使用较大的块大小,例如 8 KB 或 16 KB。

8.6.3.3.3 DB_FILE_MULTIBLOCK_READ_COUNT

DB_FILE_MULTIBLOCK_READ_COUNT 参数确定使用单个操作系统 READ 调用读取多少数据库块。

此参数的默认值是对应于可以有效执行的最大 I/O 大小的值。 最大 I/O 大小值取决于平台,大多数平台为 1 MB。 如果将 DB_FILE_MULTIBLOCK_READ_COUNT 设置为过高的值,则操作系统会在启动数据库时将该值降低到允许的最高级别。

8.6.3.3.4 DISK_ASYNCH_IO and TAPE_ASYNCH_IO

DISK_ASYNCH_IO 和 TAPE_ASYNCH_IO 参数启用或禁用操作系统的异步 I/O 工具。

DISK_ASYNCH_IO 和 TAPE_ASYNCH_IO 参数的推荐值为 TRUE。 这些参数使查询服务器进程能够在执行表扫描时将 I/O 请求与处理重叠。 如果操作系统支持异步 I/O,请将这些参数保留为默认值 TRUE。

图 8-6 异步读取

当前支持并行表扫描、散列连接、排序和串行表扫描的异步操作。 但是,此功能可能需要特定于操作系统的配置,并且可能并非在所有平台上都受支持。

Monitoring Parallel Execution Performance

在尝试诊断并行执行性能问题时,您应该执行以下类型的监视。

这些类型的监控包括:

  • 使用动态性能视图监控并行执行性能
  • 监控会话统计
  • 监控系统统计
  • 监控操作系统统计信息

8.7.1 Monitoring Parallel Execution Performance with Dynamic Performance Views

您可以使用动态性能视图监控并行执行性能。

Oracle 数据库实时监控特性使您能够在 SQL 语句执行时监控它们的性能。 当 SQL 语句并行运行或单次执行消耗了至少 5 秒的 CPU 或 I/O 时间时,SQL 监控会自动启动。

在您的系统运行几天后,您应该监控并行执行性能统计数据以确定您的并行处理是否最佳。 使用本节中讨论的任何视图执行此操作。

在 Oracle Real Application Clusters 中,本节中描述的视图的全局版本聚合了来自多个实例的统计信息。 全局视图的名称以 G 开头,例如 GVFILESTAT代表VFILESTAT 代表 VFILESTAT代表VFILESTAT,等等。

8.7.1.1 V$PX_BUFFER_ADVICE

您可以使用 V$PX_BUFFER_ADVICE 动态性能视图监控并行执行性能。

V$PX_BUFFER_ADVICE 视图提供有关所有并行查询的历史和预计最大缓冲区使用情况的统计信息。 您可以参考此视图来重新配置 SGA 大小,以应对并行查询的内存不足问题。

select * from V$PX_BUFFER_ADVICE;STATISTIC                         VALUE    CON_ID
Servers Highwater                       16         0
Buffers HWM                            151         0
Estimated Buffers HWM                  240         0
Servers Max                            320         0
Estimated Buffers Max                77760         0
Buffers Current Free                  8640         0
Buffers Current Total                 8640         0 7 rows selected.

8.7.1.2 V$PX_SESSION

您可以使用 V$PX_SESSION 动态性能视图监控并行执行性能。

V$PX_SESSION 视图显示有关查询服务器会话、组、集和服务器编号的数据。 它还显示有关代表并行执行工作的进程的实时数据。 此表包括有关请求的并行度 (DOP) 和授予操作的实际 DOP 的信息。

8.7.1.3 V$PX_SESSTAT

您可以使用 V$PX_SESSTAT 动态性能视图监控并行执行性能。

VPXSESSTAT视图提供了来自VPX_SESSTAT 视图提供了来自 VPXS​ESSTAT视图提供了来自VPX_SESSION 和 V$SESSTAT 表的会话信息的连接。 因此,标准会话可用的所有会话统计信息可用于使用并行执行执行的所有会话。

8.7.1.4 V$PX_PROCESS

您可以使用 V$PX_PROCESS 动态性能视图监控并行执行性能。

V$PX_PROCESS 视图包含有关并行进程的信息,包括状态、会话 ID、进程 ID 和其他信息。

8.7.1.5 V$PX_PROCESS_SYSSTAT

您可以使用 V$PX_PROCESS_SYSSTAT 动态性能视图监控并行执行性能。

V$PX_PROCESS_SYSSTAT 视图显示查询服务器的状态并提供缓冲区分配统计信息。

8.7.1.6 V$PQ_SESSTAT

您可以使用 V$PQ_SESSTAT 动态性能视图监控并行执行性能。

V$PQ_SESSTAT 视图显示系统中所有当前服务器组的状态,例如有关查询如何分配进程以及多用户和负载平衡算法如何影响默认值和提示值的数据。

查看来自这些视图的数据后,您可能需要调整一些参数设置以提高性能。 在这种情况下,请参阅为并行执行调整通用参数的讨论。 定期查询这些视图以监控长时间运行的并行操作的进度。

对于许多动态性能视图,您必须将参数 TIMED_STATISTICS 设置为 TRUE,以便 Oracle 数据库收集每个视图的统计信息。 您可以使用 ALTER SYSTEM 或 ALTER SESSION 语句来打开和关闭 TIMED_STATISTICS。

8.7.1.7 V$PQ_TQSTAT

您可以使用 V$PQ_TQSTAT 动态性能视图监控并行执行性能。

举个简单的例子,考虑两个表之间的哈希连接,一个只有两个不同值的列的连接。 充其量,这个哈希函数对并行执行服务器 A 有一个哈希值,对并行执行服务器 B 有另一个散列值。2 的 DOP 很好,但如果是 4,则至少有两个并行执行服务器没有工作。 要发现这种类型的偏差,请使用类似于以下示例的查询:

SELECT dfo_number, tq_id, server_type, process, num_rows
FROM V$PQ_TQSTAT ORDER BY dfo_number DESC, tq_id, server_type, process;

解决此问题的最佳方法可能是选择不同的连接方法; 嵌套循环连接可能是最好的选择。 或者,如果一个连接表相对于另一个较小,则可以使用 PQ_DISTRIBUTE 提示来提示 BROADCAST 分发方法。 优化器考虑 BROADCAST 分发方法,但要求将 OPTIMIZER_FEATURES_ENABLE 设置为 9.0.2 或更高版本。

现在,假设您有一个具有高基数的连接键,但一个值包含大部分数据,例如,按年份划分的熔岩灯销售量。 唯一有大销量的年份是 1968 年,用于 1968 年记录的并行执行服务器不堪重负。 您应该使用与上一段中描述的相同的纠正措施。

V$PQ_TQSTAT 视图在表队列级别提供消息流量的详细报告。 V$PQ_TQSTAT 数据仅在从正在执行并行 SQL 语句的会话中查询时才有效。 表队列是查询服务器组之间、并行执行协调器和查询服务器组之间或查询服务器组和协调器之间的管道。 表队列在操作列中由 PX SEND (例如,PX SEND HASH)和 PX RECEIVE 显式表示。

V$PQ_TQSTAT 在每个表队列中读取或写入的每个查询服务器进程都有一行。 将 10 个消费者进程连接到 10 个生产者进程的表队列在视图中有 20 行。 通过 TQ_ID 和表队列标识符对字节列和组进行总计,以获得通过每个表队列发送的总字节数。 将此与优化器估计进行比较; 较大的变化可能表明需要使用更大的样本来分析数据。

计算按 TQ_ID 分组的字节的方差。 较大的差异表明工作负载不平衡。 您应该调查较大的差异,以确定生产者是否开始时数据分布不均,或者分布本身是否偏斜。 如果数据本身有偏差,这可能表示基数较低或不同值的数量较少。

8.7.1.8 V$RSRC_CONS_GROUP_HISTORY

您可以使用 V$RSRC_CONS_GROUP_HISTORY 动态性能视图监控并行执行性能。

VRSRCCONSGROUPHISTORY视图显示VRSRC_CONS_GROUP_HISTORY 视图显示 VRSRCC​ONSG​ROUPH​ISTORY视图显示VRSRC_PLAN_HISTORY 中具有非 NULL 计划的每个条目的消费者组统计历史记录,包括有关并行语句排队的信息。

8.7.1.9 V$RSRC_CONSUMER_GROUP

您可以使用 V$RSRC_CONSUMER_GROUP 动态性能视图监控并行执行性能。

V$RSRC_CONSUMER_GROUP 视图显示与当前活动的资源使用者组相关的数据,包括有关并行语句的信息。

8.7.1.10 V$RSRC_PLAN

您可以使用 V$RSRC_PLAN 动态性能视图监控并行执行性能。

V$RSRC_PLAN 视图显示所有当前活动资源计划的名称,包括并行语句排队的状态。

8.7.1.11 V$RSRC_PLAN_HISTORY

您可以使用 V$RSRC_PLAN_HISTORY 动态性能视图监控并行执行性能。

V$RSRC_PLAN_HISTORY 显示在实例上启用、禁用或修改资源计划的历史记录。 历史包括并行语句排队的状态

8.7.1.12 V$RSRC_SESSION_INFO

您可以使用 V$RSRC_SESSION_INFO 动态性能视图监控并行执行性能。

V$RSRC_SESSION_INFO 视图显示每个会话的资源管理器统计信息,包括并行语句队列统计信息。 列包括 PQ_SERVERS 和 PQ_STATUS。

如果会话处于活动状态并正在运行并行查询,则 V$RSRC_SESSION_INFO 视图的 PQ_SERVERS 列包含活动并行服务器的数量。 如果查询已排队,则会显示此查询尝试运行的并行服务器的数量。

PQ_STATUS 列维护并行语句排队的原因

8.7.1.13 V$RSRCMGRMETRIC

您可以使用 V$RSRCMGRMETRIC 动态性能视图监控并行执行性能。

V$RSRCMGRMETRIC 视图显示与并行语句队列相关的统计信息。

与并行语句排队相关的统计信息被添加到资源管理器指标中,该指标获取给定一分钟窗口的统计信息并将它们保留大约一小时。

列包括 AVG_ACTIVE_PARALLEL_STMTS、AVG_QUEUED_PARALLEL_STMTS、AVG_ACTIVE_PARALLEL_SERVERS、AVG_QUEUED_PARALLEL_SERVERS 和 PARALLEL_SERVERS_LIMIT。

8.7.2 Monitoring Session Statistics

您可以使用动态性能视图监控会话统计信息以诊断并行执行性能。

使用 GV$PX_SESSION 确定并行执行的服务器组的配置。 在此示例中,会话 9 是查询协调器,而会话 7 和 21 位于第一组,第一组。 会话 18 和 20 属于第一组,第二组。 此查询的请求和授予的 DOP 为 2,如以下查询的输出所示:

SELECT QCSID, SID, INST_ID "Inst", SERVER_GROUP "Group", SERVER_SET "Set",DEGREE "Degree", REQ_DEGREE "Req Degree"
FROM GV$PX_SESSION ORDER BY QCSID, QCINST_ID, SERVER_GROUP, SERVER_SET;

您的输出应类似于以下内容:

QCSID      SID        Inst       Group      Set        Degree     Req Degree
---------- ---------- ---------- ---------- ---------- ---------- ---------- 9          9          1 9          7          1          1          1          2          2 9         21          1          1          1          2          2 9         18          1          1          2          2          2 9         20          1          1          2          2          2

对于单个实例,使用 SELECT FROM V$PX_SESSION 并且不要包含列名 Instance ID。

上一个示例的输出中显示的进程使用 GV$PX_SESSION 协作完成相同的任务。 下一个示例显示了连接查询的执行,以确定这些进程在物理读取方面的进度。 使用此查询来跟踪任何特定的统计信息:

SELECT QCSID, SID, INST_ID "Inst", SERVER_GROUP "Group", SERVER_SET "Set",NAME "Stat Name", VALUE
FROM GV$PX_SESSTAT A, V$STATNAME B
WHERE A.STATISTIC# = B.STATISTIC# AND NAME LIKE 'PHYSICAL READS'AND VALUE > 0 ORDER BY QCSID, QCINST_ID, SERVER_GROUP, SERVER_SET;

您的输出应类似于以下内容:

QCSID  SID   Inst   Group  Set    Stat Name          VALUE
------ ----- ------ ------ ------ ------------------ ---------- 9     9      1               physical reads           3863 9     7      1      1      1 physical reads              2 9    21      1      1      1 physical reads              2 9    18      1      1      2 physical reads              2 9    20      1      1      2 physical reads              2

使用前一种查询来跟踪 V$STATNAME 中的统计信息。 根据需要重复此查询以观察查询服务器进程的进度。

下一个查询使用 V$PX_PROCESS 检查查询服务器的状态。

SELECT * FROM V$PX_PROCESS;

您的输出应类似于以下内容:

SERV STATUS    PID    SPID      SID    SERIAL# IS_GV   CON_ID
---- --------- ------ --------- ------ ------- -----  -------
P002 IN USE        16     16955     21   7729  FALSE        0
P003 IN USE        17     16957     20   2921  FALSE        0
P004 AVAILABLE     18     16959                FALSE        0
P005 AVAILABLE     19     16962                FALSE        0
P000 IN USE        12      6999     18   4720  FALSE        0
P001 IN USE        13      7004      7    234  FALSE        0

8.7.3 Monitoring System Statistics

您可以使用动态性能视图监控系统统计信息,以诊断并行执行性能。

V$SYSSTAT 和 V$SESSTAT 视图包含几个用于监视并行执行的统计信息。 使用这些统计信息来跟踪并行查询、DML、DDL、数据流运算符 (DFO) 和操作的数量。 每个查询、DML 或 DDL 都可以有多个并行操作和多个 DFO。

此外,由于自适应多用户算法或可用并行执行服务器的耗尽,统计数据还计算了 DOP 减少或降级的查询操作的数量。

最后,这些视图中的统计信息还计算代表并行执行发送的消息数。 以下语法是如何显示这些统计信息的示例:

SELECT NAME, VALUE FROM GV$SYSSTATWHERE UPPER (NAME) LIKE '%PARALLEL OPERATIONS%'OR UPPER (NAME) LIKE '%PARALLELIZED%' OR UPPER (NAME) LIKE '%PX%';

您的输出应类似于以下内容:

NAME                                           VALUE
queries parallelized                                 100
DML statements parallelized                           84
DDL statements parallelized                            0
DFO trees parallelized                               287
Parallel operations not downgraded                   288
Parallel operations downgraded to serial               0
Parallel operations downgraded 75 to 99 pct            0
Parallel operations downgraded 50 to 75 pct            0
Parallel operations downgraded 25 to 50 pct            0
Parallel operations downgraded 1 to 25 pct             0
PX local messages sent                            104792
PX local messages recv'd                          104792
PX remote messages sent                                0
PX remote messages recv'd                              0 14 rows selected.

以下查询显示了系统上每个工作人员(子进程)和查询协调进程的当前等待状态:

SELECT px.SID "SID", p.PID, p.SPID "SPID", px.INST_ID "Inst",px.SERVER_GROUP "Group", px.SERVER_SET "Set",px.DEGREE "Degree", px.REQ_DEGREE "Req Degree", w.event "Wait Event"
FROM GV$SESSION s, GV$PX_SESSION px, GV$PROCESS p, GV$SESSION_WAIT w
WHERE s.sid (+) = px.sid AND s.inst_id (+) = px.inst_id ANDs.sid = w.sid (+) AND s.inst_id = w.inst_id (+) ANDs.paddr = p.addr (+) AND s.inst_id = p.inst_id (+)
ORDER BY DECODE(px.QCINST_ID,  NULL, px.INST_ID,  px.QCINST_ID), px.QCSID,
DECODE(px.SERVER_GROUP, NULL, 0, px.SERVER_GROUP), px.SERVER_SET, px.INST_ID;

8.7.4 Monitoring Operating System Statistics

Oracle 数据库中可用的信息与通过操作系统实用程序(例如基于 UNIX 的系统上的 sar 和 vmstat)可用的信息之间存在相当大的重叠。

操作系统提供有关 I/O、通信、CPU、内存和分页、调度和同步原语的性能统计信息。 V$SESSTAT 视图还提供操作系统统计信息的主要类别。

通常,有关 I/O 设备和信号量操作的操作系统信息比 Oracle 数据库信息更难映射回数据库对象和操作。然而,一些操作系统具有良好的可视化工具和收集数据的有效手段。

有关 CPU 和内存使用情况的操作系统信息对于评估性能非常重要。可能最重要的统计数据是 CPU 使用率。低级性能调优的目标是在所有 CPU 上成为 CPU 绑定。完成此操作后,您可以在 SQL 级别工作以找到可能更密集 I/O 但使用更少 CPU 的替代计划。

操作系统内存和分页信息对于微调控制内存在内存密集型数据仓库子系统(如并行通信、排序和散列连接)之间如何分配的许多系统参数很有价值。

8.8 Tips for Tuning Parallel Execution

8.8.1 Implementing a Parallel Execution Strategy

实施良好的并行执行策略对于确保高性能非常重要。

一个好的策略的建议包括:

  • 实施简单的设置以了解系统中发生的情况。
  • 使用资源管理器为使用者组指定最大并行度 (DOP),以便为每个组分配特定数量的处理资源,而不会使系统不堪重负。使用并行执行时需要资源管理策略来控制系统,并确保 SQL 语句能够并行执行。
  • 您的策略基于您希望为并行执行提供的系统资源量。调整参数 PARALLEL_MAX_SERVERS 和 PARALLEL_SERVERS_TARGET 的值以限制系统中运行的并行执行 (PX) 服务器的数量。
  • 考虑采用 ELT(提取、加载和转换)策略而不是 ETL(提取、转换和加载)策略。
  • 使用带有并行 SQL 语句(例如 CTAS 或 IAS)的外部表来加快数据加载

8.8.2 Optimizing Performance by Creating and Populating Tables in Parallel

要优化检索大型结果集的查询的并行执行性能,请并行创建和填充表。

Oracle 数据库无法将结果并行返回给用户进程。 如果查询返回大量行,则查询的执行可能确实会更快。 但是,用户进程只能串行接收行。 要优化检索大型结果集的查询的并行执行性能,请使用 PARALLEL CREATE TABLE AS SELECT 或直接路径 INSERT 将结果集存储在数据库中。 稍后,用户可以串行查看结果集。

并行执行 SELECT 不会影响 CREATE 语句。 但是,如果 CREATE 语句是并行执行的,那么优化器也会尝试使 SELECT 也并行运行。

当与 NOLOGGING 选项结合使用时,CREATE TABLE AS SELECT 的并行版本提供了一个非常有效的中间表工具,例如:

CREATE TABLE summary PARALLEL NOLOGGING AS SELECT dim_1, dim_2 ...,
SUM (meas_1)
FROM facts GROUP BY dim_1, dim_2;

这些表也可以通过并行 INSERT 增量加载。 您可以使用以下技术利用中间表:

  • 公共子查询可以计算一次并多次引用。 这可以允许对星型模式的一些查询(特别是没有选择性 WHERE 子句谓词的查询)更好地并行化。 使用星形转换技术具有选择性 WHERE 子句谓词的星形查询可以有效地自动并行化,而无需对 SQL 进行任何修改。
  • 将复杂查询分解为更简单的步骤,以提供应用程序级检查点或重新启动。 例如,1 TB 数据库上的复杂多表连接可能会运行数十个小时。 此查询期间的失败将意味着从头开始。 使用 CREATE TABLE AS SELECT 或 PARALLEL INSERT AS SELECT,您可以将查询重写为一系列更简单的查询,每个查询运行几个小时。 如果发生系统故障,可以从最后完成的步骤重新开始查询。
  • 通过创建一个忽略原始表中不需要的行的新表,然后删除原始表,有效地实施手动并行删除操作。 或者,您可以使用方便的并行删除功能,直接从原始表中删除行。
  • 为高效的多维向下钻取分析创建汇总表。 例如,汇总表可能存储按月、品牌、地区和销售员分组的收入总和。
  • 通过将旧表复制到新表来重组表、消除链接行、压缩可用空间等。 这比导出/导入快得多,也比重新加载更容易。
  • 请务必使用 DBMS_STATS 包来收集有关新创建的表的优化器统计信息。 为避免 I/O 瓶颈,请指定一个表空间,该表空间至少在与 CPU 一样多的物理磁盘上进行条带化。 为避免分配空间时产生碎片,表空间中的文件数应为 CPU 数的倍数

8.8.3 Using EXPLAIN PLAN to Show Parallel Operations Plans

使用 EXPLAIN PLAN 语句查看并行查询的执行计划。

EXPLAIN PLAN 输出在 COST、BYTES 和 CARDINALITY 列中显示优化器信息。 您还可以使用 utlxplp.sql 脚本来显示 EXPLAIN PLAN 输出以及所有相关的并行信息。

有几种方法可以优化连接语句的并行执行。 您可以更改系统配置,调整本章前面讨论的参数,或使用提示,例如 DISTRIBUTION 提示。

使用 EXPLAIN PLAN 时的要点是:

  • 验证优化器选择性估计。如果优化器认为查询只产生一行,它倾向于使用嵌套循环。这可能表明未对表进行分析,或者优化器对同一表上多个谓词的相关性做出了不正确的估计。可能需要扩展统计信息或提示来为优化器提供正确的选择性或强制优化器使用另一种连接方法。
  • 在低基数连接键上使用哈希连接。如果连接键几乎没有不同的值,则哈希连接可能不是最佳的。如果不同值的数量小于并行度 (DOP),则某些并行查询服务器可能无法处理特定查询。
  • 考虑数据倾斜。如果连接键涉及过度的数据倾斜,则哈希连接可能需要一些并行查询服务器比其他服务器工作得更多。如果优化器没有选择它,请考虑使用提示来引发 BROADCAST 分发方法。仅当 OPTIMIZER_FEATURES_ENABLE 设置为 9.0.2 或更高时,优化器才会考虑 BROADCAST 分发方法。有关详细信息,请参阅 V$PQ_TQSTAT。

8.8.3.1 Example: Using EXPLAIN PLAN to Show Parallel Operations

您可以使用 EXPLAIN PLAN 来显示并行操作。

以下示例说明了优化器打算如何执行并行查询:

explain plan for SELECT /*+ PARALLEL */ cust_first_name, cust_last_name FROM customers c, sales s WHERE c.cust_id = s.cust_id;----------------------------------------------------------
| Id  | Operation                       |  Name          |
----------------------------------------------------------
|   0 | SELECT STATEMENT                |                |
|   1 |  PX COORDINATOR                 |                |
|   2 |   PX SEND QC (RANDOM)           | :TQ10000       |
|   3 |    NESTED LOOPS                 |                |
|   4 |     PX BLOCK ITERATOR           |                |
|   5 |      TABLE ACCESS FULL          | CUSTOMERS      |
|   6 |     PARTITION RANGE ALL         |                |
|   7 |      BITMAP CONVERSION TO ROWIDS|                |
|   8 |       BITMAP INDEX SINGLE VALUE | SALES_CUST_BIX |
----------------------------------------------------------Note
------ automatic DOP: Computed Degree of Parallelism is 2

8.8.4 Additional Considerations for Parallel DML

当您想要在数据仓库上使用并行插入、更新或删除操作来刷新数据仓库数据库时,在设计物理数据库时需要考虑其他问题。 这些注意事项不会影响并行执行操作。 这些问题是:

  • 并行 DML 和直接路径限制
  • 并行度的限制
  • 何时增加 INITRANS
  • Segment 的可用 Transaction Free Lists 数量限制
  • 用于大量重做日志的多个归档器
  • 数据库写入器进程 (DBWn) 工作负载
  • [NO]LOGGING 子句

8.8.4.1 Parallel DML and Direct-Path Restrictions

本主题中确定了并行 DML 和直接路径操作的限制。

如果违反了并行限制,则简单地串行执行操作。 如果违反了直接路径 INSERT 限制,则忽略 APPEND 提示并执行常规插入操作。 不返回错误信息。

8.8.4.2 Limitation on the Degree of Parallelism

根据使用的 Oracle 数据库的软件级别,并行度有一定的限制。

对于不具有并行 DML itl 不变属性的表(在 Oracle9i 第 2 版 (9.2) 之前创建的表或使用 COMPATIBLE 初始化参数设置为小于 9.2 创建的表),并行度 (DOP) 等于 分区或子分区。 这意味着,如果表未分区,则查询将连续运行。 要确定哪些表没有此属性,请发出以下语句:

SELECT u.name, o.name FROM obj$ o, tab$ t, user$ uWHERE o.obj# = t.obj# AND o.owner# = u.user#AND bitand(t.property,536870912) != 536870912;

8.8.4.3 When to Increase INITRANS

在某些情况下,您应该增加 INITRANS 的值。

如果您有全局索引,则全局索引段和全局索引块由同一并行 DML 语句的服务器进程共享。 即使这些操作不是针对同一行执行的,服务器进程也可以共享相同的索引块。 每个服务器事务都需要索引块头中的一个事务条目才能对块进行更改。

在这种情况下,当使用 CREATE INDEX 或 ALTER INDEX 语句时,您应该将 INITRANS(在每个数据块中分配的初始事务数)设置为较大的值,例如针对该索引的最大 DOP。

8.8.4.4 Limitation on Available Number of Transaction Free Lists for Segments

字典管理的表空间中段的可用事务空闲列表数量是有限制的。

创建段后,进程和事务空闲列表的数量是固定的,不能更改。如果您在段标头中指定大量进程空闲列表,您可能会发现这会限制可用事务空闲列表的数量。下次重新创建段头时,您可以通过减少进程空闲列表的数量来减轻此限制;这为段标头中的事务空闲列表留出了更多空间。

对于 UPDATE 和 DELETE 操作,每个服务器进程都可能需要自己的事务空闲列表。因此,并行 DML DOP 受到表上可用事务空闲列表的最小数量以及 DML 语句必须维护的任何全局索引的有效限制。例如,如果表有 25 个事务空闲列表,并且表有两个全局索引,一个有 50 个事务空闲列表,一个有 30 个事务空闲列表,则 DOP 限制为 25。如果表有 40 个事务空闲列表,则DOP 将被限制为 30。

STORAGE 子句的 FREELISTS 参数用于设置进程空闲列表的数量。默认情况下,不会创建进程空闲列表。

事务空闲列表的默认数量取决于块大小。例如,如果没有明确设置进程空闲列表的数量,则默认情况下,一个 4 KB 的块大约有 80 个事务空闲列表。事务空闲列表的最小数量为 25。

8.8.4.5 Multiple Archivers for Large Numbers of Redo Logs

归档大量重做日志需要多个归档进程。

并行 DDL 和并行 DML 操作会产生大量的重做日志。 归档这些重做日志的单个 ARCH 进程可能无法跟上。 为避免此问题,您可以手动或使用作业队列生成多个归档程序进程。

8.8.4.6 Database Writer Process (DBWn) Workload

在某些情况下,您应该增加数据库写入进程的数量。

并行 DML 操作在短时间内使用缓冲区高速缓存中的大量数据、索引和撤消块。 例如,假设您在查询 V$SYSTEM_EVENT 视图后看到大量 free_buffer_waits,如以下语法所示:

SELECT TOTAL_WAITS FROM V$SYSTEM_EVENT WHERE EVENT = 'FREE BUFFER WAITS';

在这种情况下,您应该考虑增加 DBWn 进程。 如果没有等待空闲缓冲区,则查询不会返回任何行。

8.8.4.7 [NO]LOGGING Clause

了解设置 [NO]LOGGING 子句时的注意事项。

[NO]LOGGING 子句适用于表、分区、表空间和索引。 如果使用 NOLOGGING 子句,则实际上不会为某些操作(例如直接路径 INSERT)生成日志。 NOLOGGING 属性不在 INSERT 语句级别指定,而是在对表、分区、索引或表空间使用 ALTER 或 CREATE 语句时指定。

当表或索引设置了 NOLOGGING 时,并行和串行直接路径 INSERT 操作都不会生成重做日志。 使用 NOLOGGING 选项集运行的进程运行得更快,因为不会生成重做。 但是,在对表、分区或索引执行 NOLOGGING 操作后,如果在执行备份之前发生介质故障,则所有已修改的表、分区和索引都可能损坏。

如果使用 NOLOGGING 子句,则直接路径 INSERT 操作(字典更新除外)永远不会生成重做日志。 NOLOGGING 属性不影响撤消,只影响重做。 准确地说,NOLOGGING 允许直接路径 INSERT 操作生成可忽略的重做量(范围无效重做,而不是完整图像重做)。

为了向后兼容,仍然支持 [UN]RECOVERABLE 作为 CREATE TABLE 语句的备用关键字。 但是,在将来的版本中可能不支持此备用关键字。所以你还可以看到SQL Loader中还用这个关键字

在表空间级别,日志记录子句指定在表空间中创建的所有表、索引和分区的默认日志记录属性。 当 ALTER TABLESPACE 语句更改现有表空间日志记录属性时,在 ALTER 语句之后创建的所有表、索引和分区都具有新的日志记录属性; 现有的不会更改其日志记录属性。 表空间级别的日志记录属性可以被表、索引或分区级别的规范覆盖。

默认的日志记录属性是 LOGGING。 但是,如果您通过发出 ALTER DATABASE NOARCHIVELOG 将数据库置于 NOARCHIVELOG 模式,那么无论指定的日志记录属性如何,所有可以在不记录的情况下完成的操作都不会生成日志。

8.8.5 Optimizing Performance by Creating Indexes in Parallel

您可以通过并行创建索引来优化性能。

多个进程可以同时工作以创建索引。 通过在多个服务器进程之间分配创建索引所需的工作,Oracle 数据库可以比单个服务器进程串行创建索引更快地创建索引。

并行索引创建的工作方式与使用 ORDER BY 子句的表扫描非常相似。 该表是随机抽样的,并找到一组索引键,将索引分成与 DOP 相同数量的块。 第一组查询进程扫描表,提取键-rowid 对,并根据键将每对发送到第二组查询进程中的进程。 第二组中的每个进程都对键进行排序并以通常的方式构建索引。 在构建完所有索引片段之后,并行执行协调器简单地连接片段(它们是有序的)以形成最终索引。

并行本地索引创建使用单个服务器集。 集合中的每个服务器进程都分配有一个表分区以进行扫描并为其构建索引分区。 因为给定 DOP 使用了一半的服务器进程,所以可以使用更高的 DOP 运行并行本地索引创建。 但是,DOP 被限制为小于或等于您要创建的索引分区的数量。 为避免此限制,您可以使用 DBMS_PCLXUTIL 包。

您可以选择指定在索引创建期间不应发生重做和撤消日志记录。 这可以显着提高性能,但会暂时使索引无法恢复。 备份新索引后恢复可恢复性。 如果您的应用程序可以容忍索引恢复需要重新创建的窗口,那么您应该考虑使用 NOLOGGING 子句。

CREATE INDEX 语句中的 PARALLEL 子句是您可以指定用于创建索引的 DOP 的唯一方法。 如果在 CREATE INDEX 语句的并行子句中未指定 DOP,则将 CPU 的数量用作 DOP。 如果没有 PARALLEL 子句,则按顺序创建索引。

并行创建索引时,STORAGE 子句引用查询服务器进程创建的每个子索引的存储。 因此,使用 5 MB 的 INITIAL 值和 12 的 DOP 创建的索引在创建索引期间至少消耗 60 MB 的存储空间,因为每个进程都以 5 MB 的范围开始。 当查询协调器进程合并已排序的子索引时,可能会修剪某些范围,并且生成的索引可能小于请求的 60 MB。

当您在表上添加或启用 UNIQUE 或 PRIMARY KEY 约束时,您无法自动并行创建所需的索引。 相反,使用 CREATE INDEX 语句和适当的 PARALLEL 子句在所需列上手动创建索引,然后添加或启用约束。 然后,Oracle 数据库在启用或添加约束时使用现有索引。

如果所有约束都处于 ENABLE NOVALIDATE 状态,则可以同时并行启用同一表上的多个约束。 在以下示例中,ALTER TABLE ENABLE CONSTRAINT 语句执行并行检查约束的表扫描:

CREATE TABLE a (a1 NUMBER CONSTRAINT ach CHECK (a1 > 0) ENABLE NOVALIDATE)
PARALLEL;
INSERT INTO a values (1);
COMMIT;
ALTER TABLE a ENABLE CONSTRAINT ach;

8.8.6 Parallel DML Tips

8.8.6.1 Parallel DML Tip 1: INSERT

使用 INSERT 语句可用的功能可以总结如表 8-5 所示:
表 8-5 INSERT 功能总结

插入类型 并行 串行 NOLOGGING
Conventional No。有关在启用并行 DML 的情况下使用 NOAPPEND 提示来执行并行常规插入的信息,请参阅本节中的文本。 Yes No
Direct-path INSERT (APPEND) 可以,但需要
ALTER SESSION ENABLE PARALLEL DML 或 ENABLE_PARALLEL_DML SQL 提示以启用 PARALLEL DML 模式
和以下之一:
用于显式设置并行度的表 PARALLEL 属性或 PARALLEL 提示
APPEND 提示以显式设置模式
或以下
ALTER SESSION FORCE PARALLEL DML 强制 PARALLEL DML 模式
Yes, 但需要APPEND hint Yes,但需要:为分区或表设置 NOLOGGING 属性

如果启用了并行 DML 并且为数据字典中的表设置了 PARALLEL 提示或 PARALLEL 属性,则插入操作是并行的并且是附加的,除非应用了限制。 如果缺少 PARALLEL 提示或 PARALLEL 属性,则按顺序执行插入操作。 当且仅当并行 DML 被启用或强制时,自动 DOP 才会并行化 SQL 语句的 DML 部分。

如果启用了并行 DML,则可以使用 NOAPPEND 提示执行并行常规插入操作。 例如,您可以将 /*+ noappend parallel */ 与 SQL INSERT 语句一起使用来执行并行常规插入。

SQL> INSERT /*+ NOAPPEND PARALLEL */ INTO sales_hist SELECT * FROM sales;

并行常规插入操作的优点是能够执行在线操作而不受直接路径插入的限制。 并行常规插入操作的缺点是该过程可能比直接路径插入要慢。

8.8.6.2 Parallel DML Tip 2: Direct-Path INSERT

追加模式是并行插入操作期间的默认模式。 数据总是插入到分配给表的新块中。 使用 APPEND 提示是可选的。 您应该使用追加模式来提高 INSERT 操作的速度,但在必须优化空间利用率时不应该这样做。 您可以使用 NOAPPEND 覆盖附加模式。

APPEND 提示适用于串行和并行插入操作。 如果您使用此提示,串行插入也会更快。 但是,APPEND 提示确实需要更多空间和锁定开销。

您可以将 NOLOGGING 与 APPEND 一起使用,以使该过程更快。 NOLOGGING 表示不为该操作生成重做日志。 NOLOGGING 绝不是默认设置; 当您想优化性能时使用它。 当表或分区需要恢复时,通常不应该使用它。 如果需要恢复,请务必在操作后立即执行备份。 使用 ALTER TABLE [NO]LOGGING 语句设置适当的值。

8.8.6.3 Parallel DML Tip 3: Parallelizing INSERT, MERGE, UPDATE, and DELETE

当表或分区在数据字典中具有 PARALLEL 属性时,该属性设置用于确定 INSERT、UPDATE 和 DELETE 语句和查询的并行度。 语句中表的显式 PARALLEL 提示会覆盖数据字典中 PARALLEL 属性的效果。

您可以使用 NO_PARALLEL 提示覆盖数据字典中表的 PARALLEL 属性。 通常,提示优先于属性。

如果会话已在 PARALLEL DML 模式下使用 ALTER SESSION ENABLE PARALLEL DML 语句启用,或者特定 SQL 语句已在 PARALLEL DML 模式下使用 ENABLE_PARALLEL_DML 提示启用,则考虑将 DML 操作用于并行化。 该模式不影响查询的并行化或 DML 语句的查询部分的并行化。

8.8.6.3.1 Parallelizing INSERT SELECT

在 INSERT … SELECT 语句中,除了 SELECT 关键字之后的提示之外,您还可以在 INSERT 关键字之后指定 PARALLEL 提示。

INSERT 关键字后的 PARALLEL 提示仅适用于 INSERT 操作,SELECT 关键字后的 PARALLEL 提示仅适用于 SELECT 操作。因此,INSERT 和 SELECT 操作的并行性是相互独立的。如果一个操作不能并行执行,则不会影响另一个操作是否可以并行执行。

如果用户已显式启用并行 DML 会话并且相关表在数据字典条目中设置了 PARALLEL 属性,则并行化插入操作的能力会导致现有行为发生变化。在这种情况下,并行化选择操作的现有 INSERT SELECT 语句也可以并行化其插入操作。

如果查询多个表,可以指定多个 SELECT PARALLEL 提示和多个 PARALLEL 属性。

示例 8-5 显示了在收购 ACME 后新增的新员工。

示例 8-5 并行化 INSERT SELECT

INSERT /*+ PARALLEL(employees) */ INTO employees
SELECT /*+ PARALLEL(ACME_EMP) */ *  FROM ACME_EMP;

此示例中不需要 APPEND 关键字,因为 PARALLEL 提示隐含了它。

8.8.6.3.2 Parallelizing UPDATE and DELETE

PARALLEL 提示(紧跟在 UPDATE 或 DELETE 关键字之后)不仅适用于底层扫描操作,也适用于 UPDATE 或 DELETE 操作。

或者,您可以在要修改的表的定义中指定的 PARALLEL 子句中指定 UPDATE 或 DELETE 并行度。

如果您已为会话或事务显式启用并行 DML,则并行化查询操作的 UPDATE 或 DELETE 语句也可以并行化其 UPDATE 或 DELETE 操作。 语句中的任何子查询或可更新视图都可以有自己单独的 PARALLEL 提示或子句,但这些并行指令不会影响并行化更新或删除的决定。 如果这些操作不能并行执行,则不会影响 UPDATE 或 DELETE 部分是否可以并行执行。

示例 8-6 显示了更新操作,为达拉斯的所有职员加薪 10%。

示例 8-6 并行化 UPDATE 和 DELETE

UPDATE /*+ PARALLEL(employees) */ employeesSET salary=salary * 1.1 WHERE job_id='CLERK' AND department_id IN(SELECT department_id FROM DEPARTMENTS WHERE location_id = 'DALLAS');

PARALLEL 提示应用于 UPDATE 操作和扫描。

示例 8-7 显示了删除所有类别 39 的产品,因为该业务线最近被分拆到一个单独的公司。

示例 8-7 并行化 UPDATE 和 DELETE

DELETE /*+ PARALLEL(PRODUCTS) */ FROM PRODUCTS WHERE category_id = 39;

同样,并行性应用于表employees 上的扫描和UPDATE 操作。

8.8.7 Incremental Data Loading in Parallel

并行 DML 与可更新的连接视图工具相结合,为刷新数据仓库系统的表提供了一种有效的解决方案。

刷新表就是用 OLTP 生产系统生成的差异数据来更新它们。

在以下示例中,假设刷新了一个名为 customers 的表,该表具有 c_key、c_name 和 c_addr 列。 差异数据包含自上次刷新数据仓库以来已更新的新行或行。 在此示例中,更新的数据通过 ASCII 文件从生产系统传送到数据仓库系统。 在开始刷新过程之前,必须将这些文件加载到名为 diff_customer 的临时表中。 您可以将 SQL*Loader 与并行和直接选项一起使用,以有效地执行此任务。 您也可以在并行加载时使用 APPEND 提示。

加载 diff_customer 后,就可以开始刷新过程了。 它可以分两个阶段执行,也可以并行合并执行,如下所示。

8.8.7.1 Optimizing Performance for Updating the Table in Parallel

以下语句是使用子查询的更新的简单 SQL 实现:

UPDATE customers SET(c_name, c_addr) = (SELECT c_name, c_addrFROM diff_customer WHERE diff_customer.c_key = customer.c_key)WHERE c_key IN(SELECT c_key FROM diff_customer);

不幸的是,该语句中的两个子查询会影响性能。

另一种方法是使用可更新的连接视图重写此查询。 要重写查询,您必须首先向 diff_customer 表添加主键约束,以确保修改后的列映射到保留键的表:

CREATE UNIQUE INDEX diff_pkey_ind ON diff_customer(c_key) PARALLEL NOLOGGING;ALTER TABLE diff_customer ADD PRIMARY KEY (c_key);

然后,您可以使用以下 SQL 语句更新客户表:

UPDATE /*+ PARALLEL(cust_joinview) */(SELECT /*+ PARALLEL(customers) PARALLEL(diff_customer) */CUSTOMER.c_name AS c_name CUSTOMER.c_addr AS c_addr,diff_customer.c_name AS c_newname, diff_customer.c_addr AS c_newaddrFROM diff_customerWHERE customers.c_key = diff_customer.c_key) cust_joinviewSET c_name = c_newname, c_addr = c_newaddr;

馈送连接视图 cust_joinview 的底层扫描是并行完成的。 然后,您可以并行化更新以进一步提高性能,但前提是客户表已分区。

8.8.7.2 Efficiently Inserting the New Rows into the Table in Parallel

本主题讨论了如何有效地将新行并行插入到表中。

刷新过程的最后阶段包括将新行从 diff_customer 临时表插入到 customers 表中。 与更新案例不同,您无法避免在 INSERT 语句中包含子查询:

INSERT /*+PARALLEL(customers)*/ INTO customers SELECT * FROM diff_customer s;

但是,您可以通过使用 HASH_AJ 提示来保证将子查询转换为反散列连接。 这样做使您可以使用并行 INSERT 有效地执行前面的语句。 即使表未分区,并行插入也适用。

8.8.7.3 Optimizing Performance by Merging in Parallel

您可以将更新和插入操作组合到一个语句中,通常称为合并,如下例所示。

MERGE INTO customers USING diff_customer
ON (diff_customer.c_key = customer.c_key) WHEN MATCHED THENUPDATE SET (c_name, c_addr) = (SELECT c_name, c_addr FROM diff_customer WHERE diff_customer.c_key = customers.c_key)
WHEN NOT MATCHED THENINSERT VALUES (diff_customer.c_key,diff_customer.c_data);

参考

  • https://docs.oracle.com/cd/E11882_01/server.112/e25523/parallel007.htm
  • https://docs.oracle.com/database/121/VLDBG/GUID-2B327BD6-3191-493A-AE5B-EB08325A664C.htm
  • https://docs.oracle.com/database/121/VLDBG/GUID-2627DC19-7EBE-4C45-A758-711BDB5E37EC.htm

Oracle 19c VLDB and Partitioning Guide 第8章:Using Parallel Execution 读书笔记相关推荐

  1. Oracle 19c VLDB and Partitioning Guide 第4章:分区管理 读书笔记

    本文为Oracle 19c VLDB and Partitioning Guide第4章Partition Administration的读书笔记. 使用分区表和索引时,分区管理是一项重要任务. 本章 ...

  2. Oracle 19c VLDB and Partitioning Guide 第1章:Introduction to Very Large Databases 读书笔记

    本文为Oracle 19c VLDB and Partitioning Guide第1章Introduction to Very Large Databases的读书笔记. 超大型数据库 (VLDB) ...

  3. Oracle 19c VLDB and Partitioning Guide 第2章:Partitioning Concepts 读书笔记

    本文为Oracle 19c VLDB and Partitioning Guide第2章Partitioning Concepts的读书笔记. 分区可提高各种应用程序的性能.可管理性和可用性,并有助于 ...

  4. Oracle 19c VLDB and Partitioning Guide 第5章:管理和维护基于时间的信息 读书笔记

    本文为Oracle 19c VLDB and Partitioning Guide第5章Managing and Maintaining Time-Based Information的读书笔记. Or ...

  5. 《Team Geek: A Software Developer's Guide to Working Well with Others》读书笔记(三)

    Chapter 3 Every Boat Needs a Captain 每艘船都需要一个船长 没有船长的船只是一个漂浮的房子,随着海浪无目的地到处漂浮. A boat without a capta ...

  6. 《Team Geek: A Software Developer's Guide to Working Well with Others》读书笔记(六)完

    Chapter 6 Users Are People, Too 与用户打交道 许多程序员完成的是自己满意的软件,而没有太多考虑用户的想法. A lot of programmers stop ther ...

  7. Oracle 19c升级路径与QA

    1关于19c升级实验环境和脚本 实验环境不需要预约,请访问下边的URL链接,下载实验虚机和查阅实验脚本. https://mikedietrichde.com/database-upgrade-han ...

  8. Oracle Parallel Execution(并行执行) .

    关于Oracle 的并行执行,Oracle 官方文档有详细的说明: Using Parallel Execution http://download.oracle.com/docs/cd/E11882 ...

  9. Oracle Parallel Execution(并行执行)

    关于Oracle 的并行执行,Oracle 官方文档有详细的说明: Using Parallel Execution http://download.oracle.com/docs/cd/E11882 ...

最新文章

  1. kivy texture图片格式和opencv numpy图片格式互转
  2. 12月21 vs2012 数据类型
  3. sort,uniq,fmt,wc,提取开头和结尾的命令的使用
  4. idea 中使用@Autowired注入mybatis Mapper接口时报错
  5. 找不到python2018解释器_python解释器安装教程的方法步骤
  6. Loj2687,jzoj3320-文本编辑器【线头dp】
  7. 【编程题目】给你 10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数...
  8. Python笔记-UiSelector中resourceId定位方式
  9. [ubuntu] tmux 窗口不是全屏
  10. IDEA如何导入git仓库的分支代码
  11. java流程控制if_[Java]Java基本语法结构(运算符,流程控制语句,if语句)
  12. 四种依恋类型_你们之间的爱情是哪种类型 | 爱情依恋关系测评
  13. 人人译视界 for Mac(智能协同翻译)
  14. 《图论及其应用》学习笔记(图和简单图)
  15. 一分钟解决微信小程序截图(截屏问题)
  16. Java算法--第二章--查找与排序(2)递归基础--佩波那契最大公约数插入排序汉诺塔
  17. Oracle11g R2相比R1的区别
  18. 零跑科技赴港上市:销量“数据打架”,真假难辨,如何取信于人?
  19. WT588F34B语音芯片单曲更换语音功能的实现与应用
  20. UDS之BootLoader刷写流程介绍

热门文章

  1. matlab 色温图,技术:图文教你了解色温及如何选择色温
  2. Proteus报错:External model DLL “ADC083X.DLL“ not found. GLE=0x000036B1
  3. 前端怎么加粗字体_泣血总结,死磕前端知识点
  4. 安装 pycuda 出现 PEP517 的错误
  5. 【缺陷管理】9:偶尔出现的缺陷如何处理?
  6. 张量的向量化vectorization、模n(mode-n)展开
  7. 507. Perfect Number
  8. 抛开元宇宙,我们来聊聊音视频技术的未来
  9. 蓝代斯克和玖道在华设立合资企业
  10. xcode 编译 c