Oracle并行查询介绍及相关hint的使用

发布时间 2023-08-16 09:46:07作者: 十亩菠萝地

并行查询

1 概念介绍

参考文章

How Parallel Execution Works --- 并行执行的工作原理 (oracle.com)

Parallel Query Concepts --- 并行查询概念 (oracle.com)

使用并行查询后,会根据SQL语句执行步骤的具体操作,将其分为可并行执行和无法并行执行,用户进程充当查询协调器来获取必要数量的并行服务器PARALLEL_MAX_SERVERS​,由并行服务器来执行SQL语句中可并行执行的一系列操作(sort、join、table scans、table population、index create)并返回数据给查询协调器,无法并行执行的部分由查询协调器来处理,最后由查询协调器返回结果给用户进程。并行查询是一种以最大的资源消耗来缩减执行时间的方式,并不是真正地缩减工作量。

​​

​并行度可以是使用hint​的方式也可以是自动计算

  • hint的方式手动指定

    EXPLAIN PLAN FOR
    SELECT /*+ PARALLEL(4) */ customers.cust_first_name, customers.cust_last_name, 
      MAX(QUANTITY_SOLD), AVG(QUANTITY_SOLD)
    FROM sales, customers
    WHERE sales.cust_id=customers.cust_id
    GROUP BY customers.cust_first_name, customers.cust_last_name;
    • 查询计划输出

      PLAN_TABLE_OUTPUT
      ---------------------------------------------------------------------------------------------------
      Plan hash value: 4060011603
      --------------------------------------------------------------------------------------------
      | Id  | Operation                  | Name      | Rows  | Bytes |    TQ  |IN-OUT| PQ Distrib |
      ---------------------------------------------------------------------------------------------
      |   0 | SELECT STATEMENT           |           |   925 | 25900 |        |      |            |
      |   1 |  PX COORDINATOR            |           |       |       |        |      |            |
      |   2 |   PX SEND QC (RANDOM)      | :TQ10003  |   925 | 25900 |  Q1,03 | P->S | QC (RAND)  |
      |   3 |    HASH GROUP BY           |           |   925 | 25900 |  Q1,03 | PCWP |            |
      |   4 |     PX RECEIVE             |           |   925 | 25900 |  Q1,03 | PCWP |            |
      |   5 |      PX SEND HASH          | :TQ10002  |   925 | 25900 |  Q1,02 | P->P | HASH       |
      |*  6 |       HASH JOIN BUFFERED   |           |   925 | 25900 |  Q1,02 | PCWP |            |
      |   7 |        PX RECEIVE          |           |   630 | 12600 |  Q1,02 | PCWP |            |
      |   8 |         PX SEND HASH       | :TQ10000  |   630 | 12600 |  Q1,00 | P->P | HASH       |
      |   9 |          PX BLOCK ITERATOR |           |   630 | 12600 |  Q1,00 | PCWC |            |
      |  10 |           TABLE ACCESS FULL| CUSTOMERS |   630 | 12600 |  Q1,00 | PCWP |            |
      |  11 |        PX RECEIVE          |           |   960 |  7680 |  Q1,02 | PCWP |            |
      |  12 |         PX SEND HASH       | :TQ10001  |   960 |  7680 |  Q1,01 | P->P | HASH       |
      |  13 |          PX BLOCK ITERATOR |           |   960 |  7680 |  Q1,01 | PCWC |            |
      |  14 |           TABLE ACCESS FULL| SALES     |   960 |  7680 |  Q1,01 | PCWP |            |
      ------------------------------------------------------------------------------------------------
      
      Predicate Information (identified by operation id):
      ---------------------------------------------------
      
         6 - access("SALES"."CUST_ID"="CUSTOMERS"."CUST_ID")
  • 默认并行度,默认面向单用户的工作负载,在多用户环境中不建议使用默认并行度

    • PARALLEL_DEGREE_POLICY​参数设置为AUTO时,会自动确定语句是否超过PARALLEL_MIN_TIME_THRESHOLD​的限制,是则根据下列公示计算DOP并行度。该参数也会根据对象的大小和访问对象的频率来考虑是否会将并行执行读取的对象放到SGA中,防止Oracle RAC环境下多个实例重复从磁盘中读取相同的数据块。

      • 单实例,DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT

      • RAC,DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT x INSTANCE_COUNT

  • 使用ALTER SESSION的方式设置自动并行度

    ALTER SESSION SET parallel_degree_policy = limited;
    ALTER TABLE emp parallel (degree default);

2 并行操作提示

2.1 PARALLEL

通过该提示指定并行线程个数,如果没有指定则自动计算DAP的值,如果想要在DML操作中使用并行,那么要在会话中设置ALTER SESSION SET ENABLE PARALLEL DML​。

SELECT /*+ PARALLEL(4) */ customers.cust_first_name, customers.cust_last_name, 
  MAX(QUANTITY_SOLD), AVG(QUANTITY_SOLD)
FROM sales, customers
WHERE sales.cust_id=customers.cust_id
GROUP BY customers.cust_first_name, customers.cust_last_name;

2.2 NOPARALLEL

如果在创建表时指定了PARALLEL​选项,那优化器会自动认为具备并行操作条件,可以使用该提示忽略表定义的PARALLEL​,生成非并行操作的执行计划。

SELECT /*+ NOPARALLEL(m) */ member_name from members m;

2.3 PQ_DISTRIBUTE

通过该提示定义主从进程之间分配各连接表的数据行,从而提高并行连接的执行速度

语法:/*+ PQ_DISTRIBUTE(table,outer_distribute,inner_distribute)*/​,其中outer_distribute​是描述外侧表的分配方法,inner_distribute​是描述内侧表的分配方法,而可以使用的分配方法有:

  • HASH,对连接列所运算的哈希函数结果值来向从进程分配行

  • BROADCAST,将外侧表的所有行发送给所有的从进程

  • PARTITION,连接列使用分区时,使用分区键值向从进程分配行

  • NONE,随机方式对连接的对象进行分区

SELECT /*+ ORDERED PQ_DISTRIBUTE(b HASH,HASH) USE_HASH(b) */ ...
FROM TAB1 a, TAB2 b
WHERE a.coll = b.col2;

SELECT /*+ ORDERED PQ_DISTRIBUTE(b BROADCAST,NONE) USE_HASH(b) */ ...
FROM TABI a, TAB2 b
WHERE a.col1 = b.col2;

2.4 PARALLEL_INDEX

按照并行方式对分区索引进行索引范围扫描,可以执行并行的个数

SELECT /* PARALLEL_INDEX(table1, index1,3)*/....

2.5 NOPARALLEL_INDEX

如果在创建索引时指定了PARALLEL​选项,那优化器会自动认为具备并行操作条件,可以使用该提示忽略索引定义的PARALLEL​,生成非并行操作的执行计划。

SELECT /*+ NOPARALLEL_INDEX(mmem_join_idx) */ ...
FROM members m
WHERE join_date between '20221111' and '20230111';