作者介绍 罗敏,从事Oracle技术研究、开发和服务工作20余年,在Oracle中国公司的10多年,分别在顾问咨询部、技术服务部担任资深技术顾问。曾参与国内银行、电信、政府等多个行业大型IT系统的建设和运维服务工作,为国内主要软件开发商和集成商进行过多场Oracle高级技术应用培训和交流活动。著有书籍《品悟性能优化》、《感悟Oracle核心技术》、《Oracle数据库技术服务案例精选》。 1 一个经典老问题 我们先叙述一个经典老问题,也就是在批处理中由于统计信息不准确,而导致的错误执行计划问题。如下图所示: 
上图是一个时间轴,基本流程如下:假设某系统每天凌晨3:00要进行批处理,其中T1表是一个中间结果表,每次在批处理开始之前已经被清空为0,在批处理中将加载大量数据,例如100万记录,在批处理结束时又清空为0。 此时,针对T1表这样数据量发生陡变表的统计信息采集成了一大问题。因为每天晚上22:00 Oracle在自动收集统计信息时,T1表为清空状态,这样Oracle在收集T1表的统计信息时记录数为0,与3:00批处理时的实际数据大相径庭。错误的统计信息,必然导致Oracle优化器产生错误的执行计划。怎么办? 2 传统办法 在本人的《品悟性能优化》一书的12.5.4“批处理中的统计信息采集”小节中,针对上述情况,基于Oracle公司最佳实践经验,曾经提出过如下三种办法: 即针对这些数据量陡变的表,将其在批处理业务中的典型数据状态的统计信息进行采集和锁定。这样,无论这些表的记录如何变化,Oracle始终根据典型数据状态的统计信息进行SQL语句执行计划的产生,从而基本确保执行计划的最优化和稳定性。 在批处理流程中,在这些表数据量发生陡变之后,在应用程序中实时进行统计信息采集,这样每次执行计划都应该是最优的。 通过在SQL语句中使用HINT,强行指定Oracle采用一种应用开发人员认为最优的执行计划。 但是,上述三种策略均存在不足。 首先,锁住统计信息策略很可能导致统计信息并不准确,例如锁住的信息为100万条,而实际数据量只有10万条,这样很可能还是导致优化器产生非最优的执行计划。这种策略也迫使DBA需要监控数据实际变化情况,从而决定是否解锁统计信息,并重新采集统计信息。这无疑加大了DBA的工作难度。 其次,实时采集统计信息策略必然导致对表进行重复扫描,资源消耗过大,而且对应用不透明。是啊,应用程序逻辑中怎么突然增加一段统计信息采集的语句?的确有点不伦不类的。 第三,使用HINT技术策略也非良策。因为Oracle早就说过:尽量不要使用HINT。再者,需要修改程序,对应有也不透明。更何况,通过HINT强行指定执行计划,也不能适应数据变化而灵活选择最优执行计划。 事实上,该问题更折射出更深层次的问题:那就是开发团队与运维团队的沟通和合作问题。是啊,开发团队只负责应用逻辑的实现,所谓统计信息采集完全是DBA的工作,开发人员才不关心什么统计信息采集和准确性呢。而数据量陡变又是应用逻辑问题,DBA又难以把握。在一些开发和运维两个部门泾渭分明的大型企业,该问题更是难上加难,难以协商和解决。 12c有新的解决方案吗?特别是针对这些数据量陡变的表能自动进行统计信息采集吗? 3 12c有解决方案了 有了!这就是12c针对批量数据加载的在线统计信息采集功能,原文叫“Online Statistics Gathering for Bulk-Load”。该功能只针对如下两种批量数据加载语句: 在上述两条语句完成的同时,Oracle将自动收集这些表的统计信息。令人叫绝的是:Oracle并不需要再扫描一遍表来收集统计信息,而是在上述两条语句执行过程中,Oracle通过内部机制就收集统计信息了,避免了多余的资源开销。因此,上述经典问题就有如下的解决方案了: 
也就是说,每天3:00批量加载之后,12c自动收集最新的统计信息,确保Oracle优化器产生最优的执行计划。这样,无需DBA,更无需应用开发人员修改程序,Oracle自己就能解决这种因数据量陡变而无法保证执行计划最优的问题了。 但是,目前Online Statistics Gathering for Bulk-Load不能自动收集索引和Histogram统计信息。虽然可以在批量加载之后,通过手工调用DBMS_STATS.GATHER_TABLE_STATS可以收集索引和Histogram统计信息,甚至Oracle在收集过程中只会收集索引和Histogram统计信息,而不再重复收集表的统计信息,但毕竟还是需要DBA干预。以本人之见,这应该是该特性的美中不足了。 4 感慨 尽管略有瑕疵,但针对该新技术,本人还是充满感慨: 近期活动: Gdevops全球敏捷运维峰会广州站 峰会官网:www.gdevops.com
|