MySQL 8.0 的 COUNT(*) 并行扫描几乎总失效,因其仅在无索引全表扫描、无 GROUP BY/LIMIT/ORDER BY/DISTINCT、普通 InnoDB 表、数据量超300万且未被缓冲池全量缓存时才可能触发;一旦含 WHERE 条件或索引可用,即退化为单线程。

MySQL 8.0 的 COUNT(*) 并行扫描几乎总失效
不是配置错了,是 MySQL 8.0 的并行聚合能力本身极其受限:COUNT(*)、SUM() 等聚合函数出现在最外层时,优化器会插入 stream_aggregate 节点,导致扫描被包裹在子节点中,EXPLAIN FORMAT=TREE 就看不到 Parallel scan。真正能触发并行的场景必须同时满足:type=ALL(无任何索引可用)、无 GROUP BY/LIMIT/ORDER BY/DISTINCT、表是普通 InnoDB 表、数据量 > 300 万行且未被缓冲池全量缓存。哪怕只加一个 WHERE status = 'active',只要 status 有索引,就直接退化为索引查找,彻底绕过并行路径。
Oracle 中 GROUP BY 并行需显式启用且避开阻塞点
Oracle 默认不为 GROUP BY 启用并行,除非你同时做到三件事:ALTER TABLE t PARALLEL 4 设置表级并行度、执行 SELECT /*+ PARALLEL(t, 4) USE_HASH_AGGREGATION */ ... 显式提示、确保统计信息最新(DBMS_STATS.GATHER_TABLE_STATS)。常见失效原因包括:ROWNUM 或 FOR UPDATE 出现在查询中;GROUP BY 字段被函数包裹(如 UPPER(name));字段含大量 NULL 值导致哈希分组重分布失败;或者会话未启用并行 DML(对 UPDATE 类聚合更新尤其关键)。
SQL Server 视图里调用标量 UDF 直接禁用并行
只要视图定义中用了标量用户定义函数(哪怕只在 SELECT 列表里),整个查询就会强制串行——这是引擎设计限制,不是参数没调对。sys.dm_exec_query_plan 中查不到 Parallel="1" 就证实被禁用。改写方案只有两种:/*+ INLINE */(SQL Server 2019+ 兼容级别 150+ 且函数简单时自动生效),或手动把函数逻辑展开成纯 SQL 表达式(比如把 dbo.calc_tax(@amt) 拆成 @amt * 0.08 + CASE WHEN @amt > 10000 THEN 200 ELSE 0 END)。重建视图或刷新元数据(sp_refreshsqlmodule)完全无效。
PostgreSQL 并行聚合受函数 PARALLEL 属性严格约束
PostgreSQL 不像 Oracle 那样靠 hint 强制,而是由函数本身的 PARALLEL 属性决定:PARALLEL UNSAFE(默认)直接阻断并行;PARALLEL RESTRICTED 允许扫描并行但函数计算只能在 leader 进程执行;只有 PARALLEL SAFE 才真正支持 worker 并发调用。用 SELECT proname, provolatile, parallel FROM pg_proc WHERE proname = 'your_func' 查属性。最容易忽略的是:即使函数标记为 SAFE,若它内部调用了 UNSAFE 函数,整个链路仍退化为串行。

















