一、什么是数据库统计信息
数据库统计信息是数据库管理系统(DBMS)中存储的关于表、索引、列等对象的元数据,用于描述数据的分布特征和存储结构。这些信息帮助查询优化器估算不同执行计划的成本,从而选择最高效的方式执行查询。
统计信息视为数据库的“数据地图”,地图越详细,优化器越能选择最佳路径(执行计划),地图过时:可能导致“迷路”(性能下降)。
二、数据库统计信息的核心内容
1.表级统计
◦ 行数(Row Count):表的总行数。
◦ 数据页数(Page Count):表占用的物理存储页数。
◦ 修改频率(Modification Counter):自上次统计后数据的增删改次数。
2. 列级统计
◦ 唯一值数量(Cardinality):列中不同值的数量(如性别列可能只有2个唯一值)。
◦ 空值比例(Null Ratio):列中空值(NULL)的比例。
◦ 数据分布直方图(Histogram):列值的分布情况(如工资列的高、中、低区间分布)。
◦ 最常出现值(MCV, Most Common Values):高频出现的值及其频率(如状态列中“已处理”占80%)。
3. 索引统计
◦ 索引基数(Index Cardinality):索引键的唯一值数量。
◦ 索引高度(Index Height):B+树索引的层级深度。
◦ 索引范围密度(Index Range Density):索引键的范围扫描效率。
三、数据库统计信息 的作用原理
数据库优化器通过统计信息回答以下问题:
数据规模:表有多大?扫描全表需要多少I/O?
示例:100万行的表更可能触发全表扫描,而10行的表可能直接缓存。
过滤效果:WHERE age > 30 会过滤多少行?
直方图显示年龄分布,优化器估算符合条件的行数。
连接成本:JOIN两个表的顺序如何影响性能?
小表(统计显示100行)与大表(1亿行)关联时,优先处理小表更高效。
索引价值:使用索引是否比全表扫描更快?
如果索引基数低(如“性别”列索引),优化器可能跳过索引。
四、数据库统计信息的更新机制
1. 自动更新
• 触发条件:当数据修改量超过阈值(如SQL Server的20%数据变化)时自动更新。
• 后台进程:如PostgreSQL的 autovacuum 进程自动收集统计信息。
2. 手动更新
-- MySQL/PostgreSQL
ANALYZE TABLE orders;
3. 更新策略
• 全量采集:FULLSCAN 精度高但资源消耗大,适合小表或关键表。
• 采样采集:如 WITH SAMPLE 30 PERCENT,平衡速度与精度。
• 分区统计:仅更新特定分区的统计信息(如Oracle分区表)。
五、数据库统计信息的更新注意事项
1.资源消耗:全表扫描更新统计信息可能消耗大量I/O和CPU,建议在低峰期操作。
2.锁问题:部分数据库(如MySQL的InnoDB)的统计信息更新是非阻塞的,可能引发短暂锁竞争。