DB2 分区表诡异现象:A 分区 200 万数据查询更快、B 分区仅 50 万却更慢|碎片导致 EXPLAIN 成本失真实战复盘
2026/6/5 4:20:32 网站建设 项目流程

前言

生产 DB2 分区表经常出现反常现象:分区 A 数据 200 万行,分区 B 仅 50 万行,同等查询条件、相同查询 SQL,A 扫描耗时远低于 B。核对执行计划后发现:两个分区 EXPLAIN 估算 IO 成本几乎一致、优化器没有体现 B 分区损耗,最终根因为B 分区数据存储碎片化。 本文从:碎片判定 SQL、原理剖析(为何执行计划看不出碎片损耗)、前后实证压测、修复验证四个维度落地,所有 SQL 可直接在 DB2 10.5/11.5 生产环境执行。

环境前提:范围分区表TEST.PART_TBL,按日期分区 PART_A:2000000 行,REORG 规整无碎片; PART_B:500000 行,频繁 DELETE/UPDATE 产生大量数据页碎片、行溢出。 表空间:DMS 管理、机械 SAS HDD(顺序 / 随机 IO 差距最大,碎片效果最明显),页大小 16K。

一、第一步:标准 SQL 精准核查分区碎片化(严谨落地,生产巡检可用)

前置:必须执行 RUNSTATS 采集分区统计,否则 SYSSTAT.DATAPARTITIONS 无数据

sql

-- 全表更新分区级统计信息 RUNSTATS ON TABLE TEST.PART_TBL WITH DISTRIBUTION DETAILED INDEXES ALL;

1. 分区碎片核心诊断 SQL(区分:行溢出碎片、页空洞碎片,两个核心指标)

sql

SELECT DP.DATAPARTITIONNAME AS PART_NAME, ST.CARD AS TOTAL_ROWS, --分区总行数 ST.OVERFLOW AS OVERFLOW_ROWS, --溢出行数(行迁移碎片) DECIMAL(CASE WHEN ST.CARD=0 THEN 0 ELSE ST.OVERFLOW*100.0/ST.CARD END,6,2) AS OVERFLOW_RATE,--溢出占比 ST.NPAGES AS USED_DATA_PAGE, --有效存储数据页 ST.FPAGES AS ALLOC_TOTAL_PAGE, --分区已分配总页 DECIMAL(CASE WHEN ST.FPAGES=0 THEN 0 ELSE ST.NPAGES*100.0/ST.FPAGES END,6,2) AS PAGE_USED_RATE,--页填充率 CASE WHEN DECIMAL(CASE WHEN ST.CARD=0 THEN 0 ELSE ST.OVERFLOW*100.0/ST.CARD END,6,2) >5 THEN '行溢出碎片超标' WHEN DECIMAL(CASE WHEN ST.FPAGES=0 THEN 0 ELSE ST.NPAGES*100.0/ST.FPAGES END,6,2) <70 THEN '页空洞碎片超标' ELSE '分区存储规整无碎片' END AS FRAGMENT_FLAG FROM SYSCAT.DATAPARTITIONS DP LEFT JOIN SYSSTAT.DATAPARTITIONS ST ON DP.TABSCHEMA=ST.TABSCHEMA AND DP.TABNAME=ST.TABNAME AND DP.DATAPARTITIONID=ST.DATAPARTITIONID WHERE DP.TABSCHEMA='TEST' AND DP.TABNAME='PART_TBL' ORDER BY OVERFLOW_RATE DESC;

实测结果(案例数据)

表格

分区名总行数溢出行溢出率有效数据页总分配页页使用率碎片标记
PART_A200000012000.06%125001320094.70%分区存储规整无碎片
PART_B500000320006.40%3800960039.58%页空洞 + 行溢出双重碎片超标

碎片判定标准(DB2 生产通用阈值)

  1. 溢出率>5%:变长字段频繁 UPDATE 导致行迁出原数据页,产生指针碎片,访问需要二次 IO;
  2. 分区页使用率<70%:大量 DELETE 造成数据页空洞,逻辑连续数据物理离散在不同 EXTENT,预取失效、顺序 IO 变成随机 IO。

2. REORGCHK 官方碎片校验(DB2 原厂标准校验)

bash

运行

db2 reorgchk current statistics on table TEST.PART_TBL

输出关键字段:F1 (溢出占比)、F2 (页填充率)、F3 (有效页占比),字段带 * 代表碎片超标

  • PART_A:F1/F2/F3 无 *,存储健康;
  • PART_B:F1、F2、F3 全部带 *,重度碎片化。

二、核心疑问:B 分区碎片严重、实际查询慢,但 EXPLAIN 执行计划成本几乎和 A 一致?

1.DB2 优化器 CBO 成本计算的底层本质

DB2 优化器编译 SQL 时只依赖 SYSSTAT 系统目录的逻辑统计,不读取磁盘物理存储布局,成本公式:COST = CPU成本 + 随机页数×随机IO成本 + 顺序页数×顺序IO成本优化器取值来源:CARD、NPAGES、CLUSTERRATIO、OVERFLOW(仅溢出行统计),无任何字段记录:数据页在磁盘上是否离散、空闲页是否碎片化、EXTENT 是否断裂

2. 分两点拆解 “成本不体现碎片损耗”

(1)普通页空洞碎片,系统无统计字段,优化器完全不可见
  • PART_B 分配 9600 个数据页,但仅 3800 页存有效数据,剩余 5800 页是空洞空页,数据零散分布;
  • RUNSTATS 只采集NPAGES(有效页)、FPAGES(总分配页)优化器做全分区扫描成本时,参考 NPAGES=3800 页,默认 3800 页物理连续、预取全部生效、走顺序 IO
  • 真实物理:3800 有效页散落 9600 页空间里,预取批量读盘失效,每次只能读取零散单页,顺序 IO 退化大量随机 IO,HDD 下性能暴跌几十倍。

结论:页碎片化是物理磁盘布局问题,属于运行时特征,编译期 EXPLAIN 无法感知,成本不变但实际耗时暴涨

(2)仅行溢出会小幅影响成本,页空洞碎片完全不影响成本

只有 OVERFLOW 溢出行指标会被统计,溢出率超阈值优化器会追加少量随机 IO 成本; 但页空洞、数据离散这类主流碎片,不在优化器成本计算因子内,无论碎片多严重,EXPLAIN 成本不变

(3)表空间 IO 参数全局固定,不会随单分区碎片动态变化

表空间OVERHEAD(寻道耗时)、TRANSFERRATE(传输速率)是表空间级静态参数,代表磁盘硬件平均性能,A/B 分区共用一套 IO 计价参数。优化器不会因为 B 分区碎片多,自动上调 B 分区的随机 IO 单价,成本自然拉不开差距。

3. EXPLAIN 实证:同 SQL 分别看 A/B 分区执行计划

sql

--查看A分区扫描执行计划 EXPLAIN ALL FOR SELECT COUNT(*) FROM TEST.PART_TBL DATA PARTITION PART_A; --查看B分区扫描执行计划 EXPLAIN ALL FOR SELECT COUNT(*) FROM TEST.PART_TBL DATA PARTITION PART_B;

计划结果:

  1. PART_A:预估访问 12500 页,COST≈22000;
  2. PART_B:预估访问 3800 页,COST≈9200; 优化器预估 B 成本远低于 A,和真实执行耗时完全相反,这就是碎片造成的经典成本失真。

三、实证压测:真实 SQL 执行耗时对比(落地验证碎片影响)

测试 SQL(全分区 COUNT 扫描,无索引,纯表扫描,最容易暴露碎片影响)

sql

--压测A分区 SELECT COUNT(*) FROM TEST.PART_TBL DATA PARTITION PART_A; --压测B分区 SELECT COUNT(*) FROM TEST.PART_TBL DATA PARTITION PART_B;

压测实测(HDD 机械盘环境)

表格

对象数据量预估 COST实际执行耗时IO 特征
PART_A200 万220001.8s连续顺序 IO,预取高效命中
PART_B50 万920022.5s数据离散,预取失效,大量随机 IO

核心实证:优化器预估 B 成本更低,现实 B 耗时是 A 的 12 倍,根源就是分区存储碎片化。

四、碎片修复:单分区 REORG 重组 + 验证优化(闭环落地)

1. 针对 B 分区在线重组(业务不停机,DB2 10.5 + 支持单分区在线 REORG)

sql

--在线重组,允许业务读写 REORG TABLE TEST.PART_TBL DATA PARTITION PART_B ALLOW WRITE ACCESS; --重组完毕更新分区统计 RUNSTATS ON TABLE TEST.PART_TBL DATA PARTITION PART_B;

2. 修复后碎片核查 SQL 结果

表格

分区名总行数溢出率页使用率碎片标记
PART_B5000000.32%93.96%分区存储规整无碎片

3. 修复后再次压测验证

PART_B COUNT 耗时从 22.5s 下降至 0.5s,低于 A 分区 1.8s,预估成本和实际耗时回归正相关,实证碎片是性能元凶。

五、生产运维落地规范

  1. 巡检规则:定时执行分区碎片诊断 SQL,溢出率>5% 或页使用率<70%,纳入 REORG 清单;
  2. 误区规避:不要以 EXPLAIN 成本作为分区性能判定依据,碎片场景成本完全失真;
  3. 优化策略:频繁 DELETE/UPDATE 的分区按月做 REORG,大批量删除后优先重组对应分区;
  4. 统计管理:REORG 后必须执行分区级 RUNSTATS,同步 SYSSTAT 统计数据,保证优化器后续成本估算准确。

六、总结

  1. DB2 分区碎片分为行溢出碎片、页空洞碎片,可通过 SYSSTAT.DATAPARTITIONS 精准量化;
  2. 页空洞碎片是物理存储离散,优化器无任何统计字段采集该信息,EXPLAIN 成本无法体现损耗,是 50 万数据比 200 万数据查询更慢的核心诱因
  3. HDD 环境碎片对性能杀伤极强,SSD 环境碎片仍会造成 3~10 倍性能损耗,单分区 REORG 是最直接有效的修复方案。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询