青年数据库学习互助会

DBA性能调优内功心法(十五):知己知彼篇——从多列到系统统计,构建性能优化的全局视野

阅读时间: 2025年08月11日
章节: 5.8 - 5.13 Oracle里的统计信息 (高级与策略篇)
摘要: 本章节是统计信息部分的收官之作。它首先介绍了多列统计信息和系统统计信息等高级概念,解决了列关联和硬件成本度量这两大难题。接着,本章节覆盖了字典及内部对象的统计信息维护。最后,通过对Oracle自动收集机制的剖析,引出了本章最终的、也是最具实践指导意义的核心——DBA应如何构建一套完善、主动、因地制宜的统计信息收集策略。


一、核心概要

本章节的核心,是指导DBA从一个统计信息的“使用者”,进阶为一个统计信息的“管理者”和“策略制定者”。

  • • 拓宽视野:将统计信息的概念,从描述“数据长什么样”(对象统计信息),扩展到描述“列之间的关系如何”(多列统计信息)以及“硬件跑起来有多快”(系统统计信息)。
  • • 关注内部:强调了数字字典和内部对象统计信息对数据库自身稳定运行的重要性。
  • • 从依赖到驾驭:剖析了Oracle的自动统计信息收集机制,并明确指出,对于核心系统,DBA必须从被动依赖转向主动管理,制定量身定制的收集策略。

二、关键概念重述与实战解读

  1. 1. 多列统计信息
  • • 是什么:也称为“扩展统计信息”,用于描述多个列之间的数据关联关系。
  • • DBA视角:这是解决列相关性导致基数估算不准问题的利器。常规统计信息假设列之间是独立的,例如,CBO会认为P(make='Toyota' and model='Camry') = P(make='Toyota') * P(model='Camry'),这显然是错误的。当WHERE子句中经常同时出现一组存在内在关联的列时,为它们创建多列统计信息,可以让CBO理解这种关联,从而做出准确得多的基数估算。
  • 2. 系统统计信息
    • • 是什么:它描述的不是数据,而是硬件系统的性能特征,如CPU速度、单块IO和多块IO的平均耗时。
    • • DBA视角:系统统计信息校准了CBO的“成本观”。它让CBO在估算成本时,能更真实地反映出在当前这台服务器上,CPU计算和物理IO之间的代价权衡。收集在系统典型负载下的“Workload”类型的系统统计信息,能让CBO在选择全表扫描(IO密集)还是索引扫描(可能CPU密集)时,做出更贴合实际的决策。
  • 3. 数字字典与内部对象统计信息
    • • 是什么:分别针对SYS用户下的数据字典表,以及X$等内存中的固定对象的统计信息。
    • • DBA视角:这两类统计信息的健康度,直接影响数据库自身的运行效率。例如,数据字典统计信息不准,可能导致SQL解析、对象编译等操作变慢;固定对象统计信息不准,可能导致对V$系列动态性能视图的查询变慢。我们应通过DBMS_STATS.GATHER_DICTIONARY_STATS和DBMS_STATS.GATHER_FIXED_OBJECTS_STATS,将它们的维护纳入常规DBA工作。
  • 4. Oracle里的自动统计信息收集
    • • 是什么:Oracle自带的一个名为GATHER_STATS_JOB的默认调度任务,通常在夜间的维护窗口自动运行,为那些统计信息缺失或陈旧(默认变化量超过10%)的对象收集信息。
    • • DBA视角:这是一个很好的“保底”机制,但绝不能在核心生产系统上完全依赖它。原因在于:它的“一刀切”策略无法满足所有对象的特定需求;它的运行时间可能与我们的批量任务冲突;对于关键业务,我们不能接受长达24小时的统计信息延迟。
  • 5. Oracle里应如何收集统计信息(策略总结)
    • • DBA视角:这是本章的最终总结,也是我们工作的行动指南。一套专业的统计信息收集策略应遵循以下原则:
    1. 1. 策略优先:为核心应用制定独立的、详细的收集策略,而不是依赖全局默认值。明确哪些表需要每天收集,哪些每周一次;哪些需要100%采样,哪些可以用默认采样率。
    2. 2. DBMS_STATS是唯一选择:全面使用DBMS_STATS包,并熟悉其丰富的参数,实现精细化控制。
    3. 3. 因“地”制宜:
    • • 数据倾斜列:在WHERE条件中频繁使用的数据倾斜列,为其创建直方图。
    • • 列关联:在WHERE条件中频繁组合使用的关联列,为其创建多列统计信息。
    • • 分区表:优先使用增量收集机制,高效维护全局统计信息。
  • 4. 主动管理:为核心系统创建自定义的收集脚本和Job,精确控制其执行时机和收集方式,并关闭或改造默认的自动任务以避免冲突。
  • 5. 懂得“锁定”:对于某些特殊用途的表(如某些全局临时表),或者为了稳定某个特定SQL的执行计划,可以使用DBMS_STATS.LOCK_TABLE_STATS来锁定其统计信息,防止被意外修改。
  • 6. 定期巡检:定期检查DBA_TABLES等视图中的LAST_ANALYZED日期,监控统计信息收集任务的成功率,确保策略得到有效执行。