基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
px 线程争用造成的 insert rt 高问题分析
更新时间:2026-08-18 06:46
问题现象
客户的两条 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 如下:
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: 64parallel_max_servers: 256parallel_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 计算的并行度。