并行执行可以使用 hint 管理,提高查询性能。并行执行框架支持的 hint 包括 ORDERED、LEADING、USE_NL、USE_HASH、USE_MERGE 等。

NO_USE_PX

如果某个 query 确定不希望走并行执行框架,使用 NO_USE_PX 拉回数据并生成本地执行计划。

PARALLEL

指定并行执行的并行度。启用 3 个 worker 并行执行扫描,如下例所示:

  1. select /*+ parallel(3) */ max(l_quantity) from lineitem;

注意

在复杂查询中,调度器可以调度 2 个 DFO 并行流水执行,此时,启用的 worker 数量为 2 倍的并行度,即 parallel * 2。

ORDERED

ordered hint 指定并行查询计划中 join 的顺序,严格按照 from 中的顺序生成。如下例所示,强制要求 customer 为左表,orders 为右表,并且使用 nested loop join:

  1. SELECT /*+ ordered use_nl(orders) */
  2. o_orderdate,
  3. o_shippriority
  4. from customer, orders
  5. where c_mktsegment = 'BUILDING' and
  6. c_custkey = o_custkey
  7. group by o_orderdate, o_shippriority;

在手写 SQL 时,ordered 较为有用,用户知道 join 的最佳顺序时,可以将表按照顺序写在 from 的后面,然后加上 ordered hint。

LEADING

leading hint 指定并行查询计划中最先 join 哪些表, leading 中表从左到右的顺序,也是 join 的顺序。它比 ordered 有更大的灵活性。

注意:

如果 ordered 和 leading 同时使用,则仅 ordered 生效。

PQ_DISTRIBUTE

PQ hint ( pq_distribute ) 指定并行查询计划中的数据分布方式。PQ hint 会改变分布式 join 时的数据分发方式。

PQ hint 的基本语法为:

pq_distribute(tablespec outer_distribution inner_distribution)

其中:

  • tablespec 指定关注的表,关注 join 的右表
  • outer_distribution 指定左表的数据分发方式
  • inner_distribution 指定右表的数据分发方式

两表的数据分发方式共有六种:

  • Hash, Hash
  • Broadcast, None
  • None, Broadcast
  • Partition, None
  • None, Partition
  • None, None

其中,带分区的两种分发方式要求左表或右表有分区,而且分区键就是 join 的键。如果不满足要求的话,PQ hint 不会生效。

  1. create table t1(c1 int primary key, c2 int, c3 int, c4 date);
  2. create index i1 on t1(c3);
  3. create table t2(c1 int(11) not null, c2 int(11) not null, c3 int(11) not null, primary key (c1, c2, c3)) partition by key(c2) partitions 4;
  4. explain basic select /*+use_px parallel(3) PQ_DISTRIBUTE(t2 BROADCAST NONE) LEADING(t1 t2)*/ * from t1 join t2 on t1.c2 = t2.c2;
  5. ================================================
  6. |ID|OPERATOR |NAME |
  7. ------------------------------------------------
  8. |0 |EXCHANGE IN DISTR | |
  9. |1 | EXCHANGE OUT DISTR |:EX10001|
  10. |2 | HASH JOIN | |
  11. |3 | EXCHANGE IN DISTR | |
  12. |4 | EXCHANGE OUT DISTR (BROADCAST)|:EX10000|
  13. |5 | PX BLOCK ITERATOR | |
  14. |6 | TABLE SCAN |t1 |
  15. |7 | PX BLOCK ITERATOR | |
  16. |8 | TABLE SCAN |t2 |
  17. ================================================

USE_NL

use_nl hint 指定 join 使用 nested loop join。需要满足 use_nl 中指定的表是 join 的右表。

如下例所示,如果希望 join1 为 nested loop join,则 hint 写法为 leading(a, (b,c)) use_nl((b,c))。和 ordered、leading hint 一起使用时,如果 use_nlj 中注明的表不是右表,则 use_nlj hint 被忽略。

image.png

USE_HASH

use_hash hint 指定 join 使用 hash join。需要满足 use_hash 中指定的表是 join 的右表。

注意:

如果没有使用 ordered、leading hint,并且优化器生成的 join 顺序中指定的表之间不是直接 join 的关系,那么 use_hash hint 会被忽略。

USE_MERGE

use_merge hint 指定 join 使用 merge join。需要满足 use_merge 中指定的表是 join 的右表。

注意:

如果没有使用 ordered、leading hint,并且优化器生成的 join 顺序中指定的表之间不是直接 join 的关系,那么 use_merge hint 会被忽略。