暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

深入解析 DBA_TAB_COL_STATISTICS 视图

原创 michaelliu 2026-02-07
199

这个视图是 Oracle 中存储表字段统计信息的核心视图,也是 CBO 计算条件选择性、制定最优执行计划的“数据依据”——简单说,CBO 就是靠这些字段判断“哪个条件过滤效果好、该优先执行”,而你之前关注的索引设计也需要基于这些字段的数值来决策。

下面我会按“核心重要性”分类解释各字段的含义和作用,重点标注 CBO 最依赖的关键字段,方便你理解和使用。

一、基础标识字段(定位统计信息所属对象)

这类字段用于确定统计信息对应的“表-字段”,是查询和筛选的基础:

字段名

含义

作用

OWNER

表的所属用户(模式)

区分不同用户下的同名表/字段,比如 SCOTT.EMP 和 HR.EMP 的字段统计信息

TABLE_NAME

表名

关联到具体的表

COLUMN_NAME

字段名

关联到表中的具体字段(如 EMP 表的 SAL、EMP_STATUS)

PARTITION_NAME

分区名

若表是分区表,该字段标识统计信息所属的分区(非分区表为 NULL)

二、CBO 核心依赖的统计字段(判断选择性、优化执行计划)

这类字段是 CBO 决策的核心依据,也是你分析“字段选择性高低”的关键:

字段名

含义

作用(CBO 视角 + 实用价值)

NUM_DISTINCT

字段的唯一值数量(去重后的值数)

✅ 核心:判断字段选择性的核心指标。<br>数值越大 → 选择性越高(如 EMPNO 唯一值=员工总数,选择性100%);<br>数值越小 → 选择性越低(如 DEPTNO 只有3个值,选择性极低)。<br>你设计索引时,优先选 NUM_DISTINCT 大的字段作为复合索引前导列。

DENSITY

密度(=1/NUM_DISTINCT)

CBO 计算“条件过滤后结果集大小”的核心参数:<br>密度越小(即 NUM_DISTINCT 越大)→ 过滤后结果集越小 → 该条件越优先执行。<br>比如 EMP_STATUS 密度=0.05(唯一值20个),比 DEPTNO 密度=0.33(唯一值3个)更优。

NUM_NULLS

字段中空值的数量

CBO 评估 IS NULL/IS NOT NULL 条件的过滤效果:<br>若 NUM_NULLS 占总行数90%,则 IS NOT NULL 条件选择性极高,CBO 会优先执行。

NUM_ROWS

统计信息采集时,该表/分区的总行数

CBO 结合 NUM_DISTINCT 计算“单值行数”(=NUM_ROWS/NUM_DISTINCT),判断条件过滤后的结果集大小。

LOW_VALUE

字段的最小值(二进制存储)

CBO 评估范围条件(如 SAL > 5000)的过滤效果,需用 UTL_RAW.CAST_TO_NUMBER 等函数转换为可读值。

HIGH_VALUE

字段的最大值(二进制存储)

同上,比如通过 HIGH_VALUE - LOW_VALUE 可判断字段值的分布范围,辅助分析选择性。

LAST_ANALYZED

统计信息最后一次采集的时间

✅ 实用:若该时间过久(比如表数据已大幅变化但未更新统计),CBO 会基于过期数据做错误决策,需执行 DBMS_STATS 更新统计。

三、辅助统计字段(补充数据分布特征)

这类字段进一步细化数据分布,让 CBO 的判断更精准:

字段名

含义

作用

AVG_COL_LEN

字段的平均长度(字节)

CBO 计算 I/O 成本时使用(字段越长,读取成本越高),对大字段(如 CLOB、长 VARCHAR2)的执行计划影响较大。

HISTOGRAM

字段是否有直方图统计

取值:NONE(无)、FREQUENCY(频率直方图)、HEIGHT BALANCED(高度平衡直方图)。<br>当字段值分布不均(如 SAL 中80%的值集中在3000-5000),直方图能让 CBO 更精准判断条件过滤效果,避免优化偏差。

SAMPLE_SIZE

采集统计信息时的抽样行数

若抽样行数远小于实际行数,统计信息可能不准确,CBO 决策会失真。

四、实用查询示例(快速分析字段选择性)

你可以通过以下 SQL 查询字段的核心统计信息,辅助判断索引设计的优先级:

SQL
-- 查询 SCOTT.EMP 表各字段的核心统计信息(转换高低值为可读格式)
SELECT
  COLUMN_NAME,
  NUM_DISTINCT, -- 唯一值数量(核心)
  DENSITY,      -- 密度(越小越好)
  NUM_NULLS,    -- 空值数
  NUM_ROWS,     -- 总行数
  UTL_RAW.CAST_TO_NUMBER(LOW_VALUE) AS LOW_VALUE,  -- 最小值(数值型字段)
  UTL_RAW.CAST_TO_NUMBER(HIGH_VALUE) AS HIGH_VALUE, -- 最大值(数值型字段)
  LAST_ANALYZED -- 最后统计时间
FROM DBA_TAB_COL_STATISTICS
WHERE OWNER = 'SCOTT'
  AND TABLE_NAME = 'EMP'
ORDER BY NUM_DISTINCT DESC; -- 按选择性从高到低排序,方便选索引字段

总结

1.         DBA_TAB_COL_STATISTICS 是 CBO 的“数据字典”,核心字段 NUM_DISTINCT(唯一值)、DENSITY(密度)、LAST_ANALYZED(统计时间)决定了 CBO 对字段选择性的判断;

2.         设计索引时,需基于该视图的 NUM_DISTINCT 优先选择高唯一值的字段(复合索引前导列);

3.         若 LAST_ANALYZED 时间过久,需更新统计信息,否则 CBO 会基于过期数据做出错误的执行计划决策;

4.         直方图(HISTOGRAM)能优化数据分布不均字段的条件评估,是提升 CBO 决策精准度的补充手段。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论