首批通过分布式安全可靠测评,为关键业务系统打造
Auto DOP 工作原理与实践
更新时间:2026-05-14 09:21
Auto DOP 是 OceanBase 数据库 V4.2.0(oceanbase-4.2.0.0-100000032023071023)版本提供的自动并行执行策略,即由数据库优化器而非用户,来自动判断是否为 Query 执行开启并行,如果开启并行,则自动确认并行度。开启 Auto DOP 策略并不意味着所有的 Query 都会并行执行,本文主要讲述 Auto DOP 的工作原理以及最佳实践。
详细说明
如何开启 Auto DOP?
系统变量 parallel_degree_policy 用于设置并行度选择策略:
parallel_degree_policy=AUTO: 开启 Auto DOP,优化器根据查询语句的实际情况,自动选择开启并行,并确定并行度。
parallel_degree_policy=MANUAL: 关闭 Auto DOP,根据
HINT、TABLE PARALLEL属性、SESSION 级 DOP 等控制并行度。
set parallel_degree_policy = auto;
set global parallel_degree_policy = manual;
set global parallel_degree_policy = auto;
如何配置 Auto DOP 策略?
Auto DOP 计算查询 DOP 时,最终给定的 DOP 大小受下面两个系统变量影响。在不同部署资源和业务负载条件下,也可以通过调整这两个参数干预 Auto DOP 行为:
parallel_min_scan_time_threshold: 用于设置对基表扫描开启并行的门限值,影响是否对查询开启并行和使用 DOP 的大小。参数单位为 ms,默认值为 1000,最小值为 10。
parallel_degree_limit: 用于限制使用 Auto DOP 后能够使用的最大 DOP。默认值为 0,此时优化器会根据租户CPU 和系统变量
parallel_servers_target限制最大 DOP。
如何判断查询使用了并行?
使用 EXPLAIN EXTENDED 命令查看 SQL 的执行计划,Outputs & filters 中算子的 DOP 信息表示并行度,Note 信息中也会显示并行度以及是否因为 Auto DOP 而开启了并行。
-- 没有统计信息,尝试动态采样
obclient [TEST]> explain extended select * from t_part where c1 > 1;
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ============================================================= |
| |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| |
| ------------------------------------------------------------- |
| |0 |PX COORDINATOR | |9960 |29434 | |
| |1 |└─EXCHANGE OUT DISTR |:EX10000|9960 |20651 | |
| |2 | └─PX PARTITION ITERATOR| |9960 |907 | |
| |3 | └─TABLE FULL SCAN |T_PART |9960 |907 | |
| ============================================================= |
| Outputs & filters: |
| ------------------------------------- |
| 0 - output([INTERNAL_FUNCTION(T_PART.C1(0x7f5fd0c20c90), T_PART.C2(0x7f5fd0c22010), T_PART.C3(0x7f5fd0c22330))(0x7f5fd0cab130)]), filter(nil), rowset=256 |
| 1 - output([INTERNAL_FUNCTION(T_PART.C1(0x7f5fd0c20c90), T_PART.C2(0x7f5fd0c22010), T_PART.C3(0x7f5fd0c22330))(0x7f5fd0cab130)]), filter(nil), rowset=256 |
| dop=1 |
| 2 - output([T_PART.C1(0x7f5fd0c20c90)], [T_PART.C2(0x7f5fd0c22010)], [T_PART.C3(0x7f5fd0c22330)]), filter(nil), rowset=256 |
| force partition granule |
| 3 - output([T_PART.C1(0x7f5fd0c20c90)], [T_PART.C2(0x7f5fd0c22010)], [T_PART.C3(0x7f5fd0c22330)]), filter([T_PART.C1(0x7f5fd0c20c90) > 1(0x7f5fd0c21600)]), rowset=256 |
| access([T_PART.C1(0x7f5fd0c20c90)], [T_PART.C2(0x7f5fd0c22010)], [T_PART.C3(0x7f5fd0c22330)]), partitions(p[0-3]) |
| is_index_back=false, is_global_index=false, filter_before_indexback[false], |
| range_key([T_PART.__pk_increment(0x7f5fd0c22a20)]), range(MIN ; MAX)always true |
| Used Hint: |
| ------------------------------------- |
| /*+ |
| |
| */ |
| Qb name trace: |
| ------------------------------------- |
| stmt_id:0, stmt_type:T_EXPLAIN |
| stmt_id:1, SEL$1 |
| Outline Data: |
| ------------------------------------- |
| /*+ |
| BEGIN_OUTLINE_DATA |
| FULL(@"SEL$1" "TEST"."T_PART"@"SEL$1") |
| PARALLEL( AUTO ) |
| OPTIMIZER_FEATURES_ENABLE('4.2.4.0') |
| END_OUTLINE_DATA |
| */ |
| Optimization Info: |
| ------------------------------------- |
| T_PART: |
| table_rows:10000 |
| physical_range_rows:10000 |
| logical_range_rows:10000 |
| index_back_rows:0 |
| output_rows:9960 |
| table_dop:1 |
| dop_method:Auto DOP |
| avaiable_index_name:[T_PART] |
| stats info:[version=0, is_locked=0, is_expired=0] |
| dynamic sampling level:1 |
| estimation method:[DYNAMIC SAMPLING FULL] |
| Plan Type: |
| DISTRIBUTED |
| Note: |
| Degree of Parallelisim is 1 because of Auto DOP |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
为什么 Auto DOP 没有开启并行?
使用 Auto DOP 策略计算基表并行度时,系统变量 parallel_min_scan_time_threshold 设置了对于基表扫描开启并行执行的最低扫描时间,其默认值为 1000ms,即当优化器估算的基表扫描代价超过 1s 时才会考虑开启并行。经验上,1s 大概能扫描 200w - 300w 行数据,DOP 与数据量的关系如下表所示:
| 数据量 | 1M | 100M | 200M | 300M |
|---|---|---|---|---|
| DOP | 1 | 3 | 10 | 10 |
并行(PX)线程的管理
普通查询使用 SQL 工作线程,并行执行使用 PX 线程。无论是 SQL 工作线程数,还是 PX 线程数,均受制于租户资源规格的限制。一个租户 Unit 最多可以分配的 PX 线程数受制于以下系统参数的设置:
| 参数名称 | 默认值 | 级别 | 说明 |
|---|---|---|---|
| px_workers_per_cpu_quota | 10 | 租户级配置项 | 每个 CPU 上可以分配的并行执行线程数,取值范围 [1,20]。 |
| parallel_servers_target | MIN CPU * px_workers_per_cpu_quota | 租户级变量 | 表示租户在每个节点上可申请的并行执行线程数量。 |
按照默认设置,一个 Unit 中可以分配的 PX 线程上限是 MIN_CPU 的 10 倍,比如一个 MIN_CPU=10 的租户在任一 OBServer 上最多可以有 100 个并行线程。如果一个 Unit 因为 parallel_servers_target 的限制导致可供分配的 PX 线程数低于并行查询的要求,则并行查询会进入等待队列。当一个租户中如时有大量的并行执行时,也可能因为较多的 PX 线程导致租户或 OBServer 的 CPU 资源紧张。
Auto DOP 的使用建议
并行执行可以加快 SQL 的执行速度,但同时也会使用更多的系统资源(CPU、内存等),短时间内发起过多的并行线程可能会对系统的正常运行带来风险。因此,我们对 Auto DOP 的使用有以下建议:
通过
parallel_degree_limit设置合理的最大 DOP 上限,避免并行线程过多导致的系统资源紧张和波动。根据业务场景,设置合理的
parallel_min_scan_time_threshold值,只对预估耗时超过限制的 SQL 开启并行。根据系统的资源状况,设置合理的
parallel_servers_target值,限制租户的最大并行线程数量。
适用版本
OceanBase 数据库 V4.2.0(oceanbase-4.2.0.0-100000032023071023)及之后更高版本。