---
title: Auto DOP 工作原理与实践-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 Auto DOP 工作原理与实践相关的常见问题和使用技巧，帮助您快速解决 Auto DOP 工作原理与实践的难题。
---
切换语言

- 简体中文
- English

划线反馈

# Auto DOP 工作原理与实践

更新时间：2026-05-14 09:21

适用版本： V4.2.x、V4.3.x 内容类型：TechNote  

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 等控制并行度。

```shell
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 而开启了并行。

```shell
-- 没有统计信息，尝试动态采样
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 的使用有以下建议：

1. 通过 `parallel_degree_limit` 设置合理的最大 DOP 上限，避免并行线程过多导致的系统资源紧张和波动。
 2. 根据业务场景，设置合理的 `parallel_min_scan_time_threshold` 值，只对预估耗时超过限制的 SQL 开启并行。
 3. 根据系统的资源状况，设置合理的 `parallel_servers_target` 值，限制租户的最大并行线程数量。

## 适用版本

OceanBase 数据库 V4.2.0（oceanbase-4.2.0.0-100000032023071023）及之后更高版本。

Previous

[对于 ORDER BY xx LIMIT xx 语句的优化策略](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000003810683)

Next

[OceanBase 数据库 V3.x 版本集群中执行 SQL 语句时出现 -4002 异常，伴随出现 micro block index mgr fail to store micro infos. 日志信息的原因和解决方法](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000003366715) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
