跳到主要内容

并行度调优

并行度(parallel_pipeline_task_num)控制单个 Fragment 在 BE 内执行时使用的工作任务数,是充分利用多核 CPU、降低查询延迟的关键参数。

调优前自检 Checklist

  • 已确认 BE 的 CPU 核数(决定并行度上限)。
  • 已通过 Profile 或监控判断瓶颈类型(CPU 密集 / 扫描密集 / 调度开销)。
  • 已了解当前查询场景(点查、JOIN/聚合、压测、复杂查询)。
  • 默认值(0,即 CPU 核数的一半)下性能确实不达预期。

核心概念

  • MPP 并行:每条查询在多个 BE 上并行执行。
  • BE 内并行:单个 BE 内通过多线程加速 Fragment 执行。
  • parallel_pipeline_task_num:单个 Fragment 在执行时使用的工作任务数,默认 0 表示 BE CPU 核数的一半。
  • 适用语句:所有 Query、DML、DDL 均支持并行执行。

调优原则

并行度并非越大越好:

  1. 提高并行度可充分利用多核资源、降低单查询延迟。
  2. 但会引入额外的数据 Shuffle 算子和多线程同步逻辑,带来资源浪费。
  3. 默认值已平衡了单查询与并发场景,通常无需用户介入
  4. Doris 在持续完善自适应策略,优先在 SQL 级或场景级做必要调整,而非全局。

场景化调参建议

以下示例假设 BE 的 CPU 核数为 16。

场景对照表

查询场景推荐并行度原因
单表点查 / WHERE 少量数据 / LIMIT / 命中物化视图1仅 1 个 Fragment,瓶颈在数据扫描线程(与查询线程独立、自适应并行),查询线程不需多并发。
大数据量两表 JOIN / 聚合查询(CPU 密集)16计算密集型,CPU 未打满时调大并行度可吃满核心;但不要无限增大(如 48 只会增加调度开销)。
压力测试场景1并发查询本身已能打满 CPU,过大并行度只会增加线程与框架调度开销。
复杂查询默认值根据 Profile 与机器负载灵活调整,可按 4 → 2 → 1 阶梯递减观察。

场景一:单表简单操作

  • 特征:单 Fragment、瓶颈在扫描线程(已自适应并行)。
  • 建议parallel_pipeline_task_num = 1
  • 理由:扫描线程与查询执行线程相互独立,多并发查询线程无法加速扫描瓶颈。

场景二:大数据量 JOIN/聚合

  • 特征:计算密集,观察 CPU 未打满。
  • 建议:在默认值基础上调大,例如 parallel_pipeline_task_num = 16
  • 理由:利用 Pipeline 执行引擎的并行能力吃满 CPU;但不应无限制增加,否则线程/框架调度开销反噬性能。

场景三:压力测试

  • 特征:并发查询数足够多,CPU 已被多查询打满。
  • 建议parallel_pipeline_task_num = 1
  • 理由:避免叠加单查询并行度造成的调度开销。

场景四:复杂查询

  • 特征:执行计划复杂,瓶颈难以一眼判定。
  • 建议:先用默认值,再依据 Profile 与机器负载,按 4 → 2 → 1 阶梯调整观察。

调参方法

Doris 支持三种粒度的并行度设置:SQL 级、会话级、全局级。优先级依次递减。

方法对比

方式作用范围适用场景风险
SQL HINT单条 SQL针对特定慢 SQL 调优无副作用,最推荐
Session 变量当前会话同会话内一组查询单行查询也会沿用,可能性能下降
Global 变量全集群所有新连接整体 CPU 利用率调整影响范围最大,慎用

SQL 级调整

  • 目的:用 HINT 精准控制单条 SQL 的并行度,最佳灵活性。

  • 命令

    SELECT /*+SET_VAR(parallel_pipeline_task_num=8)*/ *
    FROM nation, lineitem
    WHERE lineitem.l_suppkey = nation.n_nationkey;

    SELECT /*+SET_VAR(parallel_pipeline_task_num=8,runtime_filter_mode=global)*/ *
    FROM nation, lineitem
    WHERE lineitem.l_suppkey = nation.n_nationkey;
  • 说明:可在同一 HINT 中叠加其他 session 变量(如 runtime_filter_mode)。

会话级调整

  • 目的:让当前会话内的所有 SQL 沿用同一并行度。

  • 命令

    SET parallel_pipeline_task_num = 8;
  • 说明:注意会话内即使是单行点查也会按此并行度执行,可能拖慢轻量查询。

全局调整

  • 目的:对所有新连接生效,影响整集群默认行为。

  • 命令

    SET GLOBAL parallel_pipeline_task_num = 8;
  • 说明:仅在确实需要调整全局 CPU 利用率时使用,否则建议留默认值。

FAQ / Troubleshooting

Q1:并行度设大了为什么反而更慢?

过大的并行度会引入更多 Shuffle 与线程同步开销,调度框架本身也有开销。例如 16 核机器设为 48 时几乎没有收益,反而增加调度成本。建议从默认值出发,按 4 → 2 → 1 阶梯调整。

Q2:单表点查为什么并行度建议设为 1?

单表点查只有一个 Fragment,瓶颈在数据扫描。扫描线程与查询执行线程是分开的,扫描线程会自适应并行,因此提升 parallel_pipeline_task_num 不会加速扫描瓶颈。

Q3:压测时为什么也建议并行度为 1?

压测本身有大量并发查询,CPU 已经打满;再叠加单查询并行只会带来线程调度与框架调度的额外开销。

Q4:默认值 0 是什么含义?

parallel_pipeline_task_num = 0 表示由 BE 自动取 CPU 核数的一半。该默认值兼顾了单查询性能与并发吞吐,多数场景无需修改。

Q5:我应该设置全局并行度还是 SQL HINT?

优先使用 SQL HINT 针对个别慢 SQL 调整。仅当确认需要整体调整集群 CPU 利用率时,再使用 SET GLOBAL

相关参数

参数作用默认值
parallel_pipeline_task_num单个 Fragment 在 BE 内的工作任务数0(BE CPU 核数 / 2)
runtime_filter_modeRuntime Filter 工作模式,常与并行度联合调优见 Runtime Filter 文档