欢迎访问 OceanBase 官网获取更多信息:https://www.oceanbase.com/
针对分区表的查询,如果查询的目标分区数大于 1,系统会自动启用并行查询,并行度 DOP 值由系统默认指定为 1。
如下例所示,创建一个分区表 ptable,对 ptable 进行全表数据的扫描操作,通过 EXPLAIN 命令查看生成的执行计划。通过执行计划可以看出,分区表默认的并行查询的 dop 值为 1。如果 OceanBase 集群一共有 3 个 OBServer,表 ptable 的 16 个分区分散在 3 个 OBServer 中,那么每一个 OBServer 都会启动一个工作线程(Worker Thread)来执行分区数据的扫描工作,一共需要启动 3 个工作线程来执行表的扫描工作。
obclient> CREATE TABLE PTABLE(c1 INT , c2 INT) PARTITION BY HASH(c1) PARTITIONS 16;
Query OK, 0 rows affected
obclient> EXPLAIN SELECT * FROM ptable\G
Query Plan: ======================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
------------------------------------------------------
|0 |PX COORDINATOR | |1600000 |737992|
|1 | EXCHANGE OUT DISTR |:EX10000|1600000 |618888|
|2 | PX PARTITION ITERATOR| |1600000 |618888|
|3 | TABLE SCAN |ptable |1600000 |618888|
======================================================
Outputs & filters:
-------------------------------------
0 - output([INTERNAL_FUNCTION(ptable.c1, ptable.c2)]), filter(nil)
1 - output([INTERNAL_FUNCTION(ptable.c1, ptable.c2)]), filter(nil), dop=1
2 - output([ptable.c1], [ptable.c2]), filter(nil)
3 - output([ptable.c1], [ptable.c2]), filter(nil),
access([ptable.c1], [ptable.c2]), partitions(p[0-15])
针对分区表,通过添加 PARALLEL Hint 启动并行查询,并指定 dop 值,通过 EXPLAIN 命令查看生成的执行计划。
obclient> EXPLAIN SELECT /*+ PARALLEL(8) */ * FROM ptable\G
Query Plan: ==================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
--------------------------------------------------
|0 |PX COORDINATOR | |1600000 |737992|
|1 | EXCHANGE OUT DISTR|:EX10000|1600000 |618888|
|2 | PX BLOCK ITERATOR| |1600000 |618888|
|3 | TABLE SCAN |ptable |1600000 |618888|
==================================================
Outputs & filters:
-------------------------------------
0 - output([INTERNAL_FUNCTION(ptable.c1, ptable.c2)]), filter(nil)
1 - output([INTERNAL_FUNCTION(ptable.c1, ptable.c2)]), filter(nil), dop=8
2 - output([ptable.c1], [ptable.c2]), filter(nil)
3 - output([ptable.c1], [ptable.c2]), filter(nil),
access([ptable.c1], [ptable.c2]), partitions(p[0-15])
通过执行计划可以看出,并行查询的 dop 值为 8。如果查询分区所在的 OBServer 的个数小于等于 dop 值,那么工作线程(总个数等于 dop 值)会按照一定的策略分配到涉及的 OBServer 上;如果查询分区所在的 OBServer 的个数大于 dop 值,那么每一个 OBServer 都会至少启动一个工作线程,一共需要启动的工作线程的数目会大于 dop 值。
例如,当 dop 值为 8 时,如果 16 个分区均匀的分布在 4 台 OBServer 节点上,那么每一个 OBServer 上都会启动 2 个工作线程来扫描其对应的分区(一共启动 8 个工作线程);如果 16 个分区分布在 16 台 OBServer 节点上(每一个节点一个分区),那么每一台 OBServer 上都会启动 1 个工作线程来扫描其对应的分区(一共启动 16 个工作线程)。
如果针对分区表的查询,查询分区数目小于等于 1,系统不会启动并行查询。如下例所示,对 ptable 的查询添加一个过滤条件 c1=1。
obclient> EXPLAIN SELECT * FROM ptable WHERE c1 = 1\G
*************************** 1. row ***************************
Query Plan:
======================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
--------------------------------------
|0 |TABLE SCAN|ptable|990 |85222|
======================================
Outputs & filters:
-------------------------------------
0 - output([ptable.c1], [ptable.c2]), filter([ptable.c1 = 1]),
access([ptable.c1], [ptable.c2]), partitions(p1)
通过执行计划可以看出,查询的目标分区个数为 1,系统没有启动并行查询。如果希望针对一个分区的查询也能够进行并行执行,就只能通过添加 PARALLEL Hint 的方式进行分区内并行查询,通过 EXPLAIN 命令查看生成的执行计划。
obclient> EXPLAIN SELECT /*+ PARALLEL(8) */ * FROM ptable WHERE c1 = 1\G
Query Plan: ================================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
------------------------------------------------
|0 |PX COORDINATOR | |990 |457 |
|1 | EXCHANGE OUT DISTR|:EX10000|990 |383 |
|2 | PX BLOCK ITERATOR| |990 |383 |
|3 | TABLE SCAN |ptable |990 |383 |
================================================
Outputs & filters:
-------------------------------------
0 - output([INTERNAL_FUNCTION(ptable.c1, ptable.c2)]), filter(nil)
1 - output([INTERNAL_FUNCTION(ptable.c1, ptable.c2)]), filter(nil), dop=8
2 - output([ptable.c1], [ptable.c2]), filter(nil)
3 - output([ptable.c1], [ptable.c2]), filter(nil),
access([ptable.c1], [ptable.c2]), partitions(p1)
说明
如果希望在查询分区数等于 1 的情况下,能够采用 Hint 的方式进行分区内并行查询,需要对应的 DOP 值大于等于 2。 如果 DOP 值为空或者小于 2 将不启动并行查询。
欢迎访问 OceanBase 官网获取更多信息:https://www.oceanbase.com/




