基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
并行执行入门实践
更新时间:2025-08-01 16:12:12
并行执行是一个深度且复杂的主题,需要经过一定的学习阶段,方能准确理解并发操作的机制,将并行执行的能力发挥到更大。为了使初学者能够迅速掌握并行执行的要点,在 OceanBase 数据库 V3.1 及以上版本中,我们提供了一个入门实践的指南。尽管本文中提供的参数不是最优选择,但可以有效地避免大多数不良情况,使初学者能够更轻松地应用并行执行的功能。
初始化环境
在 AP 租户下设置:
/* MySQL */
SET GLOBAL parallel_servers_target = MIN_CPU * 20;
/* Oracle */
ALTER SYSTEM SET parallel_servers_target = MIN_CPU * 20;
其中 MIN_CPU 表示 CPU 规格的下限,关于设置每个 Server 上并行查询排队条件的详细信息,参见 parallel_servers_target。
统计信息搜集
V3.x 版本的统计信息搜集跟合并绑定,所以在导入数据之后,需要发起一轮合并才能保证统计信息的搜集。
V4.x 版本在导入数据之后,可以直接调用 DBMS 统计信息包来搜集统计信息。
更多关于统计信息,请参考 统计信息概述。
设置 Hint
每条 SQL 的并行度(DOP),最大不要超过物理 CPU 数量的 1.5 倍。 一般来说,如果没有多个 SQL 并发执行,单条 SQL 的并行度可以设置为 CPU 数。例如,系统的物理 CPU 数为 32,那么 Hint 就设置为 /*+ PARALLEL(32) */。
性能调优
- 通过
top -H查看租户 CPU 使用情况。 - 单条 SQL 性能不符合预期,请使用
sql_plan_monitor获取性能报告。
-- open_dt 表示算子从 Open 到 Close 的时间间隔
-- row_dt 表示算子从吐出第一行,到吐出 OB_ITER_END 的时间间隔
-- 如果值为 NULL,表示没有吐出过第一行或者没有吐出过 OB_ITER_END
-- 请给慢 SQL 增加一个 Hint: /*+ monitor */
-- 执行增加 Hint 后的慢 SQL,可以得到 Trace_id,替换下面的 Yxxxxxxxxx,执行下面的 SQL
-- MySQL 租户:
-- 汇总:
SELECT op_id, op, rows, rescan, threads, (close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, concat(lpad('', plan_depth, ' '), plan_operation) op, sum(output_rows) rows, sum(STARTS) rescan, min(first_refresh_time) open_time, max(last_refresh_time) close_time, min(first_change_time) first_row_time, max(last_change_time) last_row_eof_time, count(1) threads from oceanbase.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' group by plan_line_id, plan_operation order by plan_line_id
) a;
-- 明细
SELECT op_id, thread, op, rows, rescan, (close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, PROCESS_NAME thread, concat(lpad('', plan_depth, ' '), plan_operation) op, output_rows rows, STARTS rescan, first_refresh_time open_time, last_refresh_time close_time, first_change_time first_row_time, last_change_time last_row_eof_time from oceanbase.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' order by plan_line_id, PROCESS_NAME
) a;
-- Oracle 租户:
--说明:open_dt 表示算子从 Open 到 Close 的时间间隔
--说明:row_dt 表示算子从吐出第一行,到吐出 OB_ITER_END 的时间间隔
--说明:如果值为 NULL,表示没有突出过第一行或者没有突出过 OB_ITER_END
-- 汇总
SELECT op_id, op, output_rows, rescan,threads ,(close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, concat(lpad(' ', max(plan_depth), ' '), plan_operation) op, sum(output_rows) output_rows, sum(STARTS) rescan, min(first_refresh_time) open_time, max(last_refresh_time) close_time, min(first_change_time) first_row_time, max(last_change_time) last_row_eof_time, count(1) threads from sys.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' group by plan_line_id, plan_operation,plan_depth order by plan_line_id
) a;
-- 明细
SELECT op_id, thread, op, output_rows, rescan, (close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, PROCESS_NAME thread, concat(lpad(' ', plan_depth, ' '), plan_operation) op, output_rows, STARTS rescan, first_refresh_time open_time, last_refresh_time close_time, first_change_time first_row_time, last_change_time last_row_eof_time from sys.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' order by plan_line_id, process_name
) a;
常见问题
Query 查询性能不符合预期,CPU 没用满? 请执行
show variables like 'parallel_servers_target确认 target 值不小于MIN_CPU* 20。PDML 性能不符合预期?
请使用
explain extended解释 PDML,确认计划走了 PDML。如果没有走 PDML,计划最底部的 Note 字段会说明原因。一般是因为被修改的表包含了 trigger、外键、local unique index等原因。如果出现
DISTRIBUTED INSERT,DISTRIBUTED UPDATE,DISTRIBUTED DELETE等字样,就说明没有走 PDML。PDML 超时,内部日志显示出现
-4138 OB_SNAPSHOT_DISCARDED报错?请调大
undo_retention参数,使其不小于 PDML 的最大执行时间。它的默认值只有 30 分钟,一旦 PDML 执行时间超过 30 分钟,就可能遇到这个问题,导致执行终止,重试,直到超时。Oceanbase V4.1 版本及以上已经无 PDML 超时问题发生,无需手动设置
undo_retention。业务不能做任何修改,如何让业务 SQL 并行起来?
OBProxy 允许用户在 Web 界面上修改连接配置,开启并行。例如,在读写分离连接上,将全部 SQL 的并行度设置为 2。