---
title: px 线程争用造成的 insert rt 高问题分析-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于px 线程争用造成的 insert rt 高问题分析相关的常见问题和使用技巧，帮助您快速解决px 线程争用造成的 insert rt 高问题分析的难题。
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# px 线程争用造成的 insert rt 高问题分析

更新时间：2026-08-18 06:46

内容类型：Troubleshoot  

## 问题现象

客户的两条 `INSERT INTO ... SELECT ... ON DUPLICATE KEY UPDATE` 语句存在不定时响应时间（RT）抖动的现象。该 INSERT 语句在正常情况下 RT 为 5-6 秒，抖动时段 RT 会超过 100-200 秒，且在 22:00 之后抖动更加剧烈。

## 问题原因

`parallel_min_scan_time_threshold` 参数设置过小（初始设置为 20 ms）。当处理大量数据时，为了使扫描性能达到该参数设定的阈值，Auto DOP 会增加 SQL 的执行并行度，导致 PX 线程的争用和等待，从而引起执行耗时的异常抖动。

## 关键信息

### SQL 信息

其中一条 SQL 如下：

```sql
INSERT
    /*+ opt_param('enable_pdml_insert_up', 'true') */
    INTO `all_car_biz_datas`(
        gmt_create,
        stat_time,
        mini_program_type,
        adcode,
        gd_service_id,
        cp_code,
        cp_type,
        type,
        price_mode,
        amap_ride_type,
        business_model,
        time_range_type,
        is_atom_data,
        cancel_before_reply_count,
        cube_hash
    )
select
    gmt_create,
    stat_time,
    mini_program_type,
    adcode,
    gd_service_id,
    cp_code,
    cp_type,
    type,
    price_mode,
    amap_ride_type,
    business_model,
    3 as time_range_type,
    case
        when cp_code is not null
        and adcode is not null
        and amap_ride_type is not null
        and gd_service_id is not null
        and mini_program_type is not null
        and type is not null
        and business_model is not null
        and price_mode is not null
        and cp_type is not null then 1
        else 0
    end as is_atom_data,
    cancel_before_reply_count,
    CONCAT(
        IFNULL(cp_code, 'ALL'),
        ';',
        IFNULL(adcode, 'ALL'),
        ';',
        IFNULL(amap_ride_type, 'ALL'),
        ';',
        IFNULL(gd_service_id, 'ALL'),
        ';',
        IFNULL(mini_program_type, 'ALL'),
        ';',
        IFNULL(type, 'ALL'),
        ';',
        IFNULL(business_model, 'ALL'),
        ';',
        IFNULL(price_mode, 'ALL'),
        ';',
        IFNULL(cp_type, 'ALL')
    ) as `cube_hash`
from
    (
        select
            /*+materialize*/
            now() as gmt_create,
            '2025-12-09 09:00:00' as stat_time,
            mini_program_type,
            adcode,
            gd_service_id,
            cp_code,
            cp_type,
            type,
            price_mode,
            amap_ride_type,
            business_model,
            count(distinct(amap_order_id)) as cancel_before_reply_count
        from
(
                select
                    dw_t.amap_order_id as amap_order_id,
                    gd_service_id,
                    mini_program_type,
                    adcode,
                    amap_ride_type,
                    business_model,
                    cp_code,
                    cp_type,
                    type,
                    price_mode
                from
                    (
                        select
                            `amap_order_id`,
                            `gd_service_id`,
                            case
                                when mini_program_type not in (
                                    0,
                                    1,
                                    2,
                                    5,
                                    14,
                                    15,
                                    71,
                                    93,
                                    99,
                                    105,
                                    106,
                                    111,
                                    112,
                                    121,
                                    124,
                                    168,
                                    175,
                                    176,
                                    177
                                ) then 10000
                                else mini_program_type
                            end as mini_program_type,
                            CASE
                                WHEN length(`adcode`) = 9 then substr(`adcode`, 1, 3)
                                WHEN `adcode` LIKE '11%' THEN '11'
                                WHEN `adcode` LIKE '31%' THEN '31'
                                WHEN `adcode` LIKE '12%' THEN '12'
                                WHEN `adcode` LIKE '50%' THEN '50'
                                ELSE substr(`adcode`, 1, 4)
                            END AS `adcode`
                        from
                            `car_order_dw`
                        WHERE
                            `status_create` >= '2025-12-09 09:00:00'
                            and `status_create` = '2025-12-09 09:00:00' - interval 30 minute
                            and gmt_create < '2025-12-09 09:00:00'
                    ) dw_t
            ) t
        group by
            mini_program_type,
            adcode,
            gd_service_id,
            cp_code,
            cp_type,
            type,
            price_mode,
            amap_ride_type,
            business_model
    ) t
ON DUPLICATE KEY UPDATE
    cancel_before_reply_count = VALUES(cancel_before_reply_count),
    cube_hash = VALUES(cube_hash),
    is_atom_data = VALUES(is_atom_data);

```

### 问题分析

- **SQL 审计对比**：对比执行快和慢的 SQL，在 `affected_rows`、`partition_cnt`、`total_wits`、`rpc_count`、读行数等指标相差不大的情况下，`EXPECTED_WORKER_COUNT` 大的，其 RT 对应更高。
 - **ASH 分析**：ASH 中也显示存在 PX 争用。从 ASH 上看主要是 `default condition wait` 这个默认等待事件。在当前版本，PX 获取线程的等待事件就是默认等待事件。在最新版本上会修复（450 442 4355），新版本 PX 等待事件会打印 `wait to acquire px worker`。
 - **日志信息**：日志中打印了 `Not enough PX thread to execute query` 信息。
 - **并行参数设置**：并行相关参数设置如下：
     - `parallel_servers_target`: 64
     - `parallel_max_servers`: 256
     - `parallel_min_scan_time_threshold`: 20 ms
 - **参数影响**：变量 `parallel_min_scan_time_threshold` 是在 Auto DOP 策略中用于计算并行度的参数，表示对基表扫描开启并行的参考执行时间。当基表扫描评估执行时间超过这个设定值时，会对基表扫描开启并行，并利用这个设定值计算一个合适的并行度。变量默认值设置为 1000，单位毫秒。通过调小 `parallel_min_scan_time_threshold` 的值，可以降低对基表开启并行的门槛限制，允许对评估执行时间更小的基表扫描开启并行，对已经开启并行且数据量固定的表，也会使用更大的并行度进行扫描。
 - **参数调整尝试**：将 `parallel_min_scan_time_threshold` 从 20 ms 调到 50 ms 效果不明显，RT 依然有抖动。
 - **手动执行分析**：手动执行查询，耗时 49 秒。从 `sql_plan_monitor` 看，请求是 20:34:03.034051 收到的，计划开始的时间是 20:34:35.179864，中间间隔了 30 多秒。
 - **并发对比**：手动加 64 并发可以 16 秒跑完。对比 64 并发和 Auto DOP 256 并发的日志，64 并发不需要等待 PX 线程，计划生成完就是直接执行的。
 - **最终方案**：采取绑定 Outline：`/*+ opt_param('enable_pdml_insert_up', 'true') parallel(64) */`，手动指定并行度。绑定后 23 点的抖动明显比 22 点抖动幅度降低。

## 问题的风险及影响

客户 SQL 执行由于 PX 线程争用导致 RT 高。

## 适用版本

所有版本。

## 解决方法

绑定 Outline：`/*+ opt_param('enable_pdml_insert_up', 'true') parallel(64) */`，手动指定并行度。

## 规避方式

- 绑定 Outline：`/*+ opt_param('enable_pdml_insert_up', 'true') parallel(64) */`，手动指定并行度。
 - 考虑给 `car_order_dw` 表建立覆盖索引，减少回表操作的数据量，进而降低 Auto DOP 计算的并行度。

上一篇

[存储过程游标执行超时导致 ORA-00600 -4067 RPC session not found](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000006802902)

下一篇

[降级的日志流副本所在的机器正常了但是仍未升级](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000006871527) ![有帮助](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) 咨询热线
