BLOCKS 表示曾写入过数据的块数,即“历史活跃块”,DELETE 不减少它,TRUNCATE 才重置;需注意 segment_type 必须大写、仅支持 LMT、依赖统计信息新鲜度。
dbms_space.space_usage 返回的 blocks 不是“当前已用块数”,而是“曾写入过数据的块数”——delete 不会减少它,truncate 才会重置。
DBMS_SPACE.SPACE_USAGE 的 7 个参数必须全填且顺序严格
少一个、类型错、大小写不对,都会直接报错:ORA-06550 或 ORA-01403。最容易出错的是第 5 个参数 segment_type:
- 必须传大写字符串,如
'TABLE'、'INDEX'、'LOBSEGMENT',不能传小写或对象名(比如'EMP') - 分区表的子段(如分区、LOB 子段)要单独调用,不能只查父表名
- 字典管理表空间(DMT)不支持,仅限本地管理表空间(LMT)
- 若未执行过
ANALYZE或DBMS_STATS.GATHER_TABLE_STATS,可能返回 0 或陈旧值
SPACE_USAGE 中的 BLOCKS 是什么含义?
它统计的是 segment 中header 已初始化、且至少发生过一次数据写入的块数,也就是“活块”。不是当前实际填充数据的块,也不是分配但空闲的块:
-
BLOCKS不随DELETE下降 —— 块仍保留格式化状态,只是变空 -
TRUNCATE后再插入,BLOCKS会从 0 开始重新增长 - 对 IOT、含 LOB 的表,主表段的
BLOCKS不包含 LOB 段的块,需单独查LOBSEGMENT - 高
FS1_BLOCKS(0–25% 空闲)可能意味着频繁小量更新 + 行迁移,需结合chain_percent判断
对比 object_space_usage 和 SPACE_USAGE 的适用场景
DBMS_SPACE.OBJECT_SPACE_USAGE 更轻量,适合快速获取“已用/分配字节数”和链接率;而 SPACE_USAGE 提供块级碎片分布(FS1–FS4、FULL、UNFORMATTED),但调用更重、依赖统计信息新鲜度:
-
OBJECT_SPACE_USAGE:只需 7 个参数中的 4 个(owner/name/type/partition),返回used_bytes、alloc_bytes、chain_percent,适合日常巡检 -
SPACE_USAGE:必须传全 15 个参数(含所有 FS* 和 FULL 变量),返回块级明细,适合深度碎片分析或收缩前评估 - 两者都不支持临时段、回滚段、undo 表空间段
- 如果目标是判断是否该
ALTER TABLE ... SHRINK SPACE,优先看FS1–FS4分布 +FULL_BLOCKS占比,而非单纯看BLOCKS
真正容易被忽略的是:BLOCKS 统计的是“历史活跃块”,不是“当前有效负载”。想看真实行密度,得结合 dba_tables.num_rows 和 avg_row_len 反推;想确认能否收缩,得先确保启用了行移动(ENABLE ROW MOVEMENT)且无基于函数的索引阻塞。











