Oracle数据库提供了几种收集统计信息的机制。
- DBMS_STATS包 :
DBMS_STATSPL / SQL包收集和管理优化的统计数据。 - 补充动态统计信息 :默认情况下,当优化器统计信息丢失,过时或不足时,数据库将在解析期间自动收集动态统计信息。数据库使用递归SQL扫描表块的少量随机样本。
- 在线统计信息收集 : 在某些情况下,DDL和DML操作会自动触发在线统计信息收集。
10.3.1 DBMS_STATS软件包
在DBMS_STATSPL / SQL程序包收集和管理优化的统计数据。
该软件包使您可以控制收集统计信息的方式和方式,包括并行度,采样方法和分区表中统计信息收集的粒度。
注意: 不要使用语句的COMPUTE and ESTIMATE子句ANALYZE来收集优化器统计信息。这些条款已被弃用。而是使用DBMS_STATS。
随DBMS_STATS包一起收集的统计信息对于创建准确的执行计划是必需的。例如,收集的表统计信息DBMS_STATS包括行数,块数和平均行长。
默认情况下,Oracle数据库使用自动优化器统计信息收集。在这种情况下,数据库将自动运行DBMS_STATS以收集所有缺少统计信息或过时的架构对象的优化器统计信息。该过程消除了与管理优化器相关的许多手动任务,并且由于统计信息丢失或过时而大大降低了生成次优执行计划的风险。您还可以通过手动执行来更新和管理优化器统计信息DBMS_STATS。
Oracle Database 19c引入了高频自动优化器统计信息收集。该轻量级任务定期收集陈旧对象的统计信息。默认间隔为15分钟。与自动统计信息收集作业相比,高频任务不会执行诸如清除不存在的对象的统计信息或调用Optimizer Statistics Advisor的操作。您可以使用以下DBMS_STATS.SET_GLOBAL_PREFS步骤为高频任务设置首选项,并使用来查看元数据DBA_AUTO_STAT_EXECUTIONS。
也可以看看:
- “ 配置自动优化器统计信息收集 ”
- “ 手动收集优化器统计信息 ”
- 《 Oracle数据库管理员指南》以了解有关自动维护任务的更多信息
- Oracle Database PL / SQL软件包和类型参考以了解
DBMS_STATS
10.3.2补充动态统计
默认情况下,当优化器统计信息丢失,过时或不足时,数据库将在解析期间自动收集动态统计信息。数据库使用递归SQL扫描表块的少量随机样本。
注意:
动态统计信息会增加统计信息,而不是提供替代方法。
动态统计信息补充了优化器统计信息,例如表和索引块计数,表和联接基数(估计的行数),联接列统计信息和GROUP BY统计信息。此信息可通过对谓词基数进行更好的估计来帮助优化器改进计划。
动态统计信息在以下情况下很有用:
- 由于谓词复杂,执行计划不是最佳的。
- 采样时间仅占查询总执行时间的一小部分。
- 该查询将执行多次,以便分摊采样时间。
10.3.3在线统计收集
在某些情况下,DDL和DML操作会自动触发在线统计信息收集。
- 批量装载 : 联机统计信息收集在以下类型的批量装载期间,数据库可以自动收集表和索引统计信息:
INSERT INTO ... SELECT使用直接路径插入和CREATE TABLE AS SELECT。 - 分区维护操作的在线统计信息收集 : Oracle数据库在特定分区维护操作期间为在线统计信息提供了类似的支持。
- 实时统计信息 : 从Oracle Database 19c开始,数据库在常规DML操作期间自动收集实时统计信息。
10.3.3.1批量装载的在线统计信息收集
在以下类型的批量加载期间,数据库可以自动收集表和索引统计信息:INSERT INTO ... SELECT使用直接路径插入和CREATE TABLE AS SELECT。
默认情况下,并行插入使用直接路径插入。您可以使用/*+APPEND*/提示强制执行直接路径插入。
注意:
在Oracle Database 19c之前 ,仅收集表统计信息,而不收集索引统计信息或直方图。 在Oracle Database 19c中,数据库维护现有的直方图,但不创建新的直方图。
在Oracle Database 19c之前 ,批量加载仅在表为空时收集在线统计信息。 从Oracle Database 19c开始,如果表不为空,则在满足以下条件时,批量加载将收集统计信息:
- 表首选项
I NCREMENTAL设置为TRUE。如果表为空,则不需要此条件。 - 对于非分区表,
INCREMENTAL_LEVEL必须将其设置为TABLE。
- 批量装载的在线统计收集的目的 : 数据仓库应用程序通常将大量数据装载到数据库中。例如,销售数据仓库可能每天,每周或每月加载数据。
- 插入分区表期间的全局统计信息 : 将行插入分区表中时,数据库将在插入过程中收集全局统计信息。
- 批量加载 : 创建直方图收集在线统计信息后,数据库不会自动创建直方图。
- 批量负载的在线统计收集限制 : 有时,批量负载的优化器统计信息收集不会自动进行。
- 用于收集批量负载的联机统计信息的用户界面 : 默认情况下,数据库在批量负载期间收集统计信息。
数据仓库应用程序通常将大量数据加载到数据库中。例如,销售数据仓库可能每天,每周或每月加载数据。
在早于Oracle Database 12c的版本中,最佳实践是在批量加载后手动收集统计信息。但是,许多应用程序在加载后由于疏忽或等待维护窗口启动收集而没有收集统计信息。缺少统计信息是执行计划不佳的主要原因。
批量加载期间自动收集统计信息具有以下优点:
- 性能提升 : 在加载期间收集统计信息可避免进行额外的表扫描以收集表统计信息。
- 改善可管理性 :批量加载后,无需用户干预即可收集统计信息。
将行插入分区表中时,数据库将在插入过程中收集全局统计信息。
例如,如果sales是分区表,并且如果运行INSERT INTO sales SELECT,则数据库将收集全局统计信息。但是,数据库不收集分区级别的统计信息。
假定使用分区扩展语法将行插入特定分区或子分区的另一种情况。在插入期间,数据库收集分区上的统计信息。但是,数据库不收集全局统计信息。
假设您正在跑步INSERT INTO sales PARTITION (sales_q4_2000) SELECT。数据库在插入期间收集统计信息。如果INCREMENTAL偏好已启用sales,则数据库还收集一个概要的sales_q4_2000。插入后即可立即获得统计信息。但是,如果回滚该事务,则数据库将自动删除在批量加载期间收集的统计信息。
也可以看看:
- “ 维护增量统计信息的注意事项 ”
- 《 Oracle数据库SQL语言参考》中的
INSERT语法和语义
收集在线统计信息后,数据库不会自动创建直方图。
如果需要直方图,然后批量加载后,Oracle建议运行DBMS_STATS.GATHER_TABLE_STATS用options=>GATHER AUTO。例如,以下程序收集myt表的统计信息:
EXEC DBMS_STATS.GATHER_TABLE_STATS(user, 'MYT', options=>'GATHER AUTO');
前面的PL / SQL程序仅收集丢失或过时的统计信息。数据库不收集在批量装入期间收集的表和基本列统计信息。
注意:您可以将表格首选项设置options来GATHER AUTO在TABLE 上,你打算批量加载。这样,您无需options在运行时显式设置参数GATHER_TABLE_STATS。
也可以看看:
- “ 收集模式和表统计信息 ”
- 《 Oracle数据库数据仓库指南》以了解有关批量加载的更多信息
10.3.3.1.4批量装载的在线统计收集限制
有时,对于批量加载,优化程序统计信息收集不会自动进行。
具体来说,当以下任何条件适用于目标表,分区或子分区时,批量加载不会自动收集统计信息:
- 它处于Oracle拥有的架构中,例如
SYS。 - 它是以下类型的表之一:嵌套表,按索引组织的表(IOT),外部表或定义为的全局临时表
ON COMMIT DELETE ROWS。注意:: 该数据库确实会自动收集混合分区表的内部分区的联机统计信息。
- 它的
PUBLISH首选项设置为FALSE。 - 其统计信息已锁定。
- 它使用多表
INSERT语句加载。
也可以看看:
- “ 收集模式和表统计信息 ”
- Oracle Database PL / SQL软件包和类型参考以了解更多信息
DBMS_STATS.SET_TABLE_PREFS
默认情况下,数据库在批量加载期间收集统计信息。
您可以通过使用GATHER_OPTIMIZER_STATISTICS提示在语句级别启用该功能。您可以使用NO_GATHER_OPTIMIZER_STATISTICS提示在语句级别禁用该功能。例如,以下语句为批量加载禁用在线统计信息收集:
CREATE TABLE employees2 AS
SELECT /*+NO_GATHER_OPTIMIZER_STATISTICS*/ * FROM employees也可以看看:
Oracle Database SQL语言参考以了解GATHER_OPTIMIZER_STATISTICS和NO_GATHER_OPTIMIZER_STATISTICS提示
10.3.3.2分区维护操作的在线统计收集
Oracle Database在特定分区维护操作期间提供了对在线统计的类似支持。
具体来说,数据库维护以下内容:
- 分区交换操作的全局统计信息。这些统计信息包括基本统计信息,摘要和直方图。交换之后,全局统计信息是传入表的统计信息和目标表的统计信息的总和。
- 以下分区操作的全局和分区级别统计信息,包括增量统计信息:
MOVEMERGECOALESCE
数据库不维护具有多个目标段的维护操作的分区级统计信息。
也可以看看:
Oracle Database VLDB和分区指南,以了解有关分区维护操作的更多信息
10.3.3.3 实时统计
从Oracle Database 19c开始,该数据库在常规DML操作期间自动收集实时统计信息。
- 实时统计的目的 : 无论是对于大负载还是常规DML,在线统计都旨在减少优化器被陈旧统计误导的可能性。
- 实时统计信息的工作 : 方式当前,当DML操作正在修改表时,Oracle数据库将动态计算最基本统计信息的值。
- 实时统计信息的用户界面 : 您可以使用PL / SQL包,数据字典视图和提示来管理和访问实时统计信息。
- 实时统计信息:示例 : 在此示例中,常规
INSERT语句触发实时统计信息的收集。
10.3.3.3.1 实时统计的目的
无论是散装负载还是常规DML,在线统计信息的目的都是减少优化器被陈旧统计信息误导的可能性。
Oracle Database 12c引入了用于收集CREATE TABLE AS SELECT语句和直接路径插入的在线统计信息。
Oracle Database 19c引入了实时统计信息,将在线支持扩展到常规DML语句。由于统计信息在DBMS_STATS工作之间可能过时,因此实时统计信息可帮助优化器生成更多最优计划。
批量加载操作会收集所有必要的统计信息,而实时统计信息 是 增加 而不是取代传统统计信息。因此,您必须继续使用定期收集统计信息DBMS_STATS,最好使用AutoTask作业。
10.3.3.3.2 实时统计如何工作
当前,当DML操作正在修改表时,Oracle数据库将动态计算最基本统计信息的值。
考虑一个事务当前正在向oe.orders表中添加数万行的情况。实时统计信息跟踪随着行插入而增加的行数。如果优化器执行新查询的硬解析,则优化器可以使用实时统计信息来获得更准确的成本估算。
10.3.3.3.3 实时统计的用户界面
您可以通过PL / SQL包,数据字典视图和提示来使用管理和访问实时统计信息。
DBMS_STATS 默认情况下,DBMS_STATS子程序包含实时统计信息。您还可以指定参数以仅包括这些统计信息。
表10-3 实时统计子程序
| 子程序 | 描述 |
|---|---|
| 这些子程序使您可以导出统计信息。默认情况下,该 |
| 这些子程序使您可以导入统计信息。默认情况下,该 |
| 这些子程序使您可以删除统计信息。默认情况下,该 |
| 此函数比较两个来源的表统计信息。统计信息始终包括实时统计信息。 |
| 此函数比较表中两个指定时间戳记之间的统计信息。统计信息始终包括实时统计信息。 |
如果有实时统计信息,则可以使用下表中的视图访问它们。请注意,不支持分区级别的统计信息,因此只有表级别的视图显示实时统计信息。该DBA_*意见有ALL_*和USER_*版本。
表10-4 实时统计信息视图
| 视图 | 描述 |
|---|---|
| 此视图显示从中提取的列统计信息和直方图信息 |
| 此视图显示当前用户可访问的表的优化程序统计信息。实时统计信息以表示 |
HINT:该NO_GATHER_OPTIMIZER_STATISTICS提示会阻止收集实时统计信息。




