1. 统计信息的基本概念与核心价值
统计信息是数据库系统中用于优化查询性能的关键元数据,它记录了表、索引等对象的详细数据分布特征。就像图书馆的图书目录卡一样,统计信息让数据库优化器能够快速判断查询路径的优劣,而无需每次都翻遍整本书。
在达梦等主流数据库中,统计信息通常包含以下核心指标:
- 表级别的总行数(cardinality)
- 列数据的唯一值数量(NDV)
- 数据分布直方图(histogram)
- 索引的选择性(selectivity)
- 数据块密度(block density)
这些指标直接影响着执行计划的生成质量。例如当优化器知道某列有1000个唯一值时,对于"WHERE col=?"这样的等值查询,就能准确估算返回行数约为总行数的1/1000。
注意:统计信息的准确性会随时间衰减,特别是对频繁更新的表。我曾遇到一个生产案例,某核心表每天新增10万数据但统计信息两周未更新,导致原本0.1秒的查询逐渐恶化到30秒。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 达梦数据库的统计信息查看方法
2.1 系统视图查询
达梦提供了丰富的系统视图来查看统计信息,最常用的是:
sql复制-- 查看表级统计信息
SELECT * FROM ALL_TAB_STATISTICS
WHERE OWNER='模式名' AND TABLE_NAME='表名';
-- 查看列级统计信息
SELECT * FROM ALL_TAB_COL_STATISTICS
WHERE OWNER='模式名' AND TABLE_NAME='表名';
-- 查看索引统计信息
SELECT * FROM ALL_IND_STATISTICS
WHERE OWNER='模式名' AND TABLE_NAME='表名';
这些视图会显示最后收集时间(LAST_ANALYZED)、样本行数(SAMPLE_SIZE)等关键信息。在我的运维经验中,当发现查询性能突然下降时,首先就应该检查这些视图中的LAST_ANALYZED时间是否过时。
2.2 执行计划验证
通过EXPLAIN可以验证统计信息对执行计划的影响:
sql复制EXPLAIN
SELECT * FROM orders WHERE customer_id = 1001;
观察执行计划中的"Rows"列,这个估算值就是基于统计信息计算的。如果发现实际执行时返回行数与估算值差异巨大(比如估算100行实际返回1万行),往往就是统计信息不准的信号。
3. 统计信息的收集方法与策略
3.1 手动收集命令
达梦提供两种主要收集方式:
sql复制-- 完整收集(推荐用于中小表)
ANALYZE TABLE 模式名.表名 COMPUTE STATISTICS;
-- 采样收集(适合大表)
ANALYZE TABLE 模式名.表名 ESTIMATE STATISTICS
SAMPLE 20 PERCENT;
在金融行业某项目中,我们对一个5亿行的交易表使用10%采样率,收集时间从全量的2小时缩短到15分钟,而生成的执行计划质量差异不到5%。
3.2 自动收集配置
达梦支持通过DBMS_STATS包配置自动收集:
sql复制-- 开启自动收集(需DBA权限)
BEGIN
DBMS_STATS.SET_GLOBAL_PREFS(
'AUTOSTATS_TARGET', 'AUTO');
END;
/
-- 设置每天凌晨2点收集
BEGIN
DBMS_STATS.SCHEDULE_STATS_JOB(
repeat_interval => 'FREQ=DAILY; BYHOUR=2');
END;
/
重要提示:自动收集虽然方便,但在高并发时段可能引发性能问题。某电商系统曾因默认设置在业务高峰触发统计信息收集,导致临时性CPU飙升至90%。建议通过以下参数控制资源占用:
sql复制DBMS_STATS.SET_PARAM('DEGREE', 4); -- 并行度 DBMS_STATS.SET_PARAM('CASCADE', TRUE); -- 级联收集索引
4. 统计信息管理的最佳实践
4.1 收集策略优化
根据表特性采用差异化策略:
- 静态表(如省份编码表):每月全量收集一次
- 中等变化表(日增万级):每周采样30%收集
- 高频变化表(如订单表):每天采样10%收集
某物流系统采用该策略后,统计信息维护时间减少60%,且未出现因统计信息不准导致的性能问题。
4.2 历史统计信息保存
达梦支持将统计信息导出到特定表:
sql复制-- 创建统计信息历史表
EXEC DBMS_STATS.CREATE_STAT_TABLE(
'SYSDBA', 'STATS_HISTORY');
-- 导出当前统计信息
EXEC DBMS_STATS.EXPORT_TABLE_STATS(
'SYSDBA', 'ORDERS', stattab=>'STATS_HISTORY');
当出现执行计划回退时,可以快速恢复:
sql复制EXEC DBMS_STATS.IMPORT_TABLE_STATS(
'SYSDBA', 'ORDERS', stattab=>'STATS_HISTORY',
statid=>'20230801_BACKUP');
4.3 监控与告警机制
建议创建监控视图跟踪统计信息健康度:
sql复制CREATE VIEW STATS_MONITOR AS
SELECT
t.OWNER, t.TABLE_NAME,
t.LAST_ANALYZED,
t.NUM_ROWS,
ROUND((SYSDATE - t.LAST_ANALYZED),1) AS DAYS_SINCE_ANALYZED,
CASE
WHEN (SYSDATE - t.LAST_ANALYZED) > 7 THEN 'CRITICAL'
WHEN (SYSDATE - t.LAST_ANALYZED) > 3 THEN 'WARNING'
ELSE 'NORMAL'
END AS STATUS
FROM ALL_TABLES t
WHERE t.OWNER NOT IN ('SYS','SYSDBA');
配合达梦作业系统,可以设置每周自动邮件发送统计信息状态报告。在某银行系统中,这套机制帮助DBA团队将因统计信息过时导致的性能问题减少了85%。
