01
—
引言
您应该收集Oracle数据库的系统统计信息吗?如果您部署过Oracle数据库,那么您会对这个问题有自己的观点,但Oracle的建议什么呢?在回答这个问题之前,我会先简短地介绍一下Oracle现有文档对这个问题的说明,然后介绍系统统计信息是如何影响SQL执行计划的。如果您想直接知道答案,可以跳过前面的部分,直接查看后面的推荐意见。
02
—
现有Oracle文档的建议
Oracle白皮书和文档对是否收集系统统计信息的建议存在一些差异,随着时间的推移也发生了一些变化。Oracle早在2001年就推出了DBMS_STATS.GATHER_SYSTEM_STATS,在Oracle Database 9i中,在官方的文档《数据库性能指南》(https://docs.oracle.com/cd/A91202_01/901_doc/server.901/a87503/stats.htm#28811)中明确指出,强烈建议收集系统统计信息。但到最近,文档的后期版本对这个问题的观点变得模棱两可。Oracle添加了一个EXADATA选项,以考虑Oracle Exadata数据库机器的特点。另一方面,《Oracle优化器白皮书》(http://www.oracle.com/technetwork/database/bi-datawarehousing/twp-bp-stats-gather-0218-4403740.pdf)建议使用系统统计默认值,而不是手动收集它们。最新的文档(http://docs.oracle.com/en/database/oracle/oracle-database/18/tgsql/gathering-optimizer-statistics.html#GUID-BABC67C0-F851-4849-906E-E2588CFD7F2B)已与这个观点保持一致。如果没有收集系统统计数据,优化器将测量数据库启动时的CPU速度,并使用默认指标计算IO成本计算。
03
—
系统统计信息如何影响SQL执行计划
系统统计信息是用于衡量系统CPU和存储子系统(如NAS、SAN、JBOD或flash)的性能,并在计算替代SQL执行计划的成本时使用此信息。SQL在执行时会消耗CPU和存储I/O的资源。通常一个SQL会有多个可选的执行计划,每个计划可能会消耗不同比例的CPU和存储I/O。Oracle优化器的工作是找到估计最少执行时间的执行计划。实际上,它使用称为成本的内部指标来比较可选的执行计划。优化器从所有的执行计划中选择估计成本最低的执行计划。如果数据库知道存储I/O和CPU的实际速度有多快,那么它可以在计算每个执行计划的成本时做出更精细的判断。例如一个SQL有三个可选的执行计划,每个计划使用不同数量的CPU和I/O。在下图中,计划1预计将使用大量CPU和很少的I/O。在这个例子中,优化器认为计划1的估计成本最低,因此选择计划1。
现在假设这个系统有一个特别高性能的存储设备。它可能会打破CPU和I/O之间的相对性能平衡。收集系统统计数据将使优化器能够考虑到这一点。在这个例子中,高性能存储的存在大大降低了计划2和计划3的相对成本,计划1的相对成本降低了很少,因为它使用的I/O较少。这个改变使计划3成为最佳选择,因为它现在的估计成本最低。
在一个拥有高性能存储设备的系统上,收集系统统计信息可以让优化器更加倾向于选择全表扫描而不是索引。
04
—
推荐意见
推荐意见是通常不需要收集系统统计信息。如果收集系统统计信息有利于您的工作负载,并且您乐于管理它们,那么您没有理由更改。但是如果您正处于决策点,需要选择是否收集它们,那么在大多数情况下,您应该使用默认值而不是收集系统统计信息。有一个特殊情况需要考虑,如果您在Oracle Exadata数据库机器上运行纯数据仓库的工作负载,可以考虑使用EXADATA选项来收集系统统计信息。这将使优化器更加倾向于选择全表扫描而不是索引,这将发挥Exadata数据库机器的优势。尽管如此,如果工作负载不是纯数据仓库类型的,或者您无法测试使用EXADATA系统统计信息的效果,那么即使在该平台上也要坚持使用默认值。重要的是要记住,如果您更改使用系统统计信息的方式,那么可能会影响SQL执行计划。因此,只有当您处于决策点,并且能够测试更改的影响,或者至少能减轻工作负载性能下降的风险时,您才可以考虑更改系统统计信息。
05
—
推荐意见的依据
这个推荐意见总会引起争议。我很清楚一些DBA和架构师非常乐意使用系统统计信息,并认为它们非常有益。这个观点没有问题,实际上在一些案例中,收集系统统计信息改变了CPU和I/O之间的相对性能平衡,并改善了一些SQL的性能。然而,这个平衡点在所有SQL中并不都位于同一个地方,因此对部分SQL来说,它可能带来的是性能下降。一组固定的系统统计信息可能不会惠及数据库处理的所有工作负载(如ETL/ELT和OLTP)。最终结果是,收集系统统计信息不太可能是全面提高性能的灵丹妙药,您可能仍然需要对一些SQL进行优化。收集系统统计信息还需要一些管理和程序的开销来维护它们,随着系统的变更和时间的推移,统计信息还可能引起SQL执行计划的变化。使用默认值可以让您避免这些问题。如果您在测试工作负载时发现收集系统统计信息可以提高性能,那么值得花一些时间来找出原因。通常不太可能是全面的性能提高。更有可能的是少数重要SQL的性能有所改善,或者可能有一组具有共同模式的SQL(例如访问一组特定的表或使用特定的谓词组合)。您可能会发现,最好将自己从管理系统统计信息中解放出来,而是使用Oracle提供的工具来优化慢SQL。据我所知,相关的MOS笔记和文档已与此观点保持一致。如果您发现任何与此相矛盾的地方,请发表评论。欢迎所有评论!