在DB2的查询优化体系里,执行计划的优劣几乎完全取决于优化器对各种访问路径和连接策略的成本估算是否准确。很多DBA遇到过一个奇怪的现象:同一SQL语句在两台配置相近的服务器上跑出了完全不同的执行计划,一台用了索引扫描,另一台却坚持全表扫描加排序。排查到最后,往往发现是CPU成本估算参数没有校准,导致优化器对CPU开销的判断出现了系统性偏差。理解opt_cpu_cost相关的成本机制,是解决这类执行计划漂移问题的必修课。

一、DB2优化器成本模型中的CPU部分是如何计算的
DB2优化器在为一条SQL生成候选执行计划时,会对每一个物理操作符估算一个成本值,这个成本由两大部分构成:IO成本和CPU成本。IO成本主要来自磁盘页面的读取次数,包括随机读和预取顺序读的差异;CPU成本则来自更细粒度的开销项,比如元组处理、谓词求值、比较操作、排序合并以及哈希表的构建与探测等。
在DB2的成本公式中,CPU部分可以粗略理解为“操作的基数乘以每次处理一个元组的CPU指令数,再除以机器的运算速度”。这里的运算速度就来自数据库管理器配置参数CPUSPEED,它表示CPU每秒能够执行的指令数(单位是百万条指令每秒,即MIPS的近似度量)。优化器把指令数除以CPUSPEED换算成时间,再与IO时间加权汇总,得到最终的成本值供计划比较使用。
需要特别注意的是,DB2的成本单位并不是直接的秒数,而是一个无量纲的加权值。CPU成本在总成本中的权重还受到DBCFG中一些参数的影响,例如在支持扩展成本模型的版本中,可以通过注册变量调整CPU与IO的相对权重。如果CPUSPEED设置得远低于真实值,优化器会认为CPU极其廉价,倾向于选择需要大量比较和哈希计算的复杂计划;反之如果设置过高,优化器会过度规避CPU密集型操作,宁可多读一些页面也要避开排序和哈希。
二、CPUSPEED的获取方式与校准方法
CPUSPEED的来源有两种:一是自动探测,二是手工设定。在创建数据库时,DB2会尝试通过跑一段基准测试来估算当前CPU的速度并写入配置;但这个探测结果受当时机器负载影响很大,如果建库时正好有批量作业在运行,探测值可能只有真实性能的一半甚至更低。二是通过db2pd -db <数据库名> -dbcfg或GET DB CFG命令查看当前值,并用UPDATE DB CFG手工覆盖。
校准的建议做法是:在业务低峰期,确保机器相对空闲,然后执行db2pd -db mydb -dbcfg | grep -i cpuspeed确认当前值,再对比官方基准或同型号服务器的典型值。一个更可靠的方式是重新运行速度探测,可以先手工设为0再重启实例,DB2会重新触发探测流程。校准之后,配合db2exfmt观察关键SQL的执行计划变化,确认成本估算是否回归合理区间。
-- 查看当前CPU速度估算 db2 get db cfg for mydb | grep -i "CPU speed" -- 手工设定CPUSPEED(示例:45000 表示约每秒4.5千万条指令) db2 update db cfg for mydb using CPUSPEED 45000 -- 使配置生效并重新收集执行计划 db2 terminate db2 connect to mydb SET CURRENT EXPLAIN MODE EXPLAIN; -- 执行业务SQL SET CURRENT EXPLAIN MODE NO; -- 格式化输出执行计划,观察成本变化 db2exfmt -d mydb -1 -o plan_after.txt
除了CPUSPEED本身,还要关注AVG_APPLS、缓冲池大小和SHEAPTHRES_SHR等参数,因为排序和哈希的成本估算会假设内存充足与否,进而影响CPU与IO成本之间的权衡。参数校准不能孤立进行,要结合工作负载整体调整。
三、通过执行计划诊断CPU成本偏差
拿到一份db2exfmt输出后,不要只看最终Total Cost,而要逐个操作符比较IO Cost和CPU Cost的构成。如果一个索引扫描节点的CPU成本远高于预期,通常意味着谓词的过滤因子估算过大,可能是统计信息陈旧或列分布倾斜;此时应先执行RUNSTATS并考虑收集列分布统计,而不是急着改配置参数。
一个典型案例:某报表SQL在开发环境走嵌套循环连接性能良好,到了生产环境却变成哈希连接且耗时翻了三倍。对比两边的执行计划发现,生产库的CPUSPEED探测值只有开发环境的四成,优化器因此低估了构建哈希表的CPU代价。将CPUSPEED修正后重启实例,执行计划恢复为原来的嵌套循环,耗时随之回落。这说明CPU成本估算偏差可以直接改变连接策略的选择方向。
在日常维护中,建议把关键SQL的执行计划纳入定期对比机制,一旦发现成本结构出现系统性漂移,先核对CPUSPEED是否被意外改动,再检查统计信息是否过期。对于从老服务器迁移到新硬件的数据库,CPUSPEED几乎一定要重新探测或手工更新,否则优化器仍在用旧机器的速度模型做决策,新硬件的优势无法体现在计划选择上。
四、调整CPU成本权重的高级手段
在较新的DB2版本中,还可以借助扩展优化器概要文件和注册变量对CPU成本施加更精细的影响。例如某些版本支持通过DB2_OPT_MAX_TEMP_SIZE等变量控制临时表空间使用倾向,间接改变排序类操作的成本评估;而优化概要文件(Optimization Profile)则可以在不修改SQL的前提下强制或引导连接顺序与连接方法,适合作为应急手段。
另一种思路是利用DB2Redistribute...之外更轻量的方式,即通过分区分布键的调整降低数据倾斜,从源头减少哈希连接中内表构建的CPU开销。无论采用哪种手段,都要遵循“先诊断、后干预”的原则:先用EXPLAIN工具量化成本构成,确认CPU成本确实是瓶颈,再选择参数校准或概要文件干预,避免盲目调整引发其他SQL计划劣化。
-- 创建优化概要文件表并启用,用于固定连接策略(应急场景) UPDATE SYSTOOLS.OPT_PROFILE SET PROFILE = ? WHERE SCHEMA = 'MYSCHEMA' AND NAME = 'FIX_JOIN'; -- 会话级别启用概要文件 SET CURRENT OPTIMIZATION PROFILE = MYSCHEMA.FIX_JOIN; -- 对比启用前后的执行计划成本 SET CURRENT EXPLAIN MODE EXPLAIN; SELECT o_orderdate, SUM(o_totalprice) FROM orders GROUP BY o_orderdate; SET CURRENT EXPLAIN MODE NO; db2exfmt -d mydb -1 -o profile_plan.txt
总结来看,opt_cpu_cost相关机制的核心在于让优化器的成本模型贴近硬件的真实表现。CPUSPEED校准是基础,统计信息维护是前提,而概要文件只是兜底工具。把这三层手段按顺序用好,绝大多数因CPU成本估算偏差导致的执行计划问题都能得到稳定解决,系统整体性能也会因此获得可预期的提升。
DB2优化器CPU成本opt_cpu_cost修改时间:2026-09-10 10:05:20