一、统计信息
统计信息是描述数据库与数据库中对象的细节信息,这些信息被优化器用来选择好的执行路径,这些信息包括:
1、表统计信息
行数
块数
平均每行长度
2、列统计信息
NULL值数量
不同值数量
数据分布
3、索引统计信息:
叶子节点块数量
二元高度
聚集因子
4、系统统计信息
I/O
CPU
统计信息主要存储在以下数据字典(分为ALL_、DBA_、USER_三大类)中:
1、表统计信息
TABLES
TAB_PARTITIONS
TAB_SUBPARTITIONS
OBJECT_TABLES
TAB_STATISTICS
2、 列统计信息
TAB_COLS
TAB_COLUMNS
NESTED_TABLE_COLS
TAB_COL_STATISTICS
PART_COL_STATISTICS
SUBPART_COL_STATISTICS
3、索引统计信息:
INDEXES
IND_PARTITIONS
IND_SUBPARTITIONS
IND_STATISTICS
二、统计信息的收集
因数据对象的中的信息是不断变化的,因而必须周期性的进行更新以反映这些变化,否则将引导优化器选择不好的、甚至是糟糕的执行计划。
统计信息的收集可分为自动收集和手动收集:
1、自动收集
从Orgacle 10g开始起,系统自动加了一个名为“GATHER_STATS_JOB”的Scheduler,它会自动对所有数据库对象进行统计信息收集。
此任务默认在周末下午10点至上午6点之间进行统计信息收集,且只有在系统中存在陈旧或丢失的统计信息时才会运行。
此任务是通过调用DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC内部存储过程实现,它对没有统计信息的对象或者是有10%的行进行修改的对象进行信息收集(依据USER_TABLE_MODIFICATIONS和ALL_TABLE_MODIFICATIONS进行判断)。
GATHER_DATABASE_STATS_JOB_PROC与GATHER_DATABASE_STATS收集信息的方式相似,不同的是GATHER_DATABASE_STATS_JOB_PROC优先对最需要统计信息的对象进行信息收集。
因而建议使用此方法以减少过多的人工操作
2、手动收集
自动收集对于数据变化适中的数据库较为合适,但对于易变的表来说,建议使用手动收集。
特别是如果对表进行了TRUNCATE、大批量DELETE、批量加载等操作,建议立即进行手动收集。
对于禁用自动收集任务,或禁用其监测机制(STATISTICS_LEVEL设置为BASIC),时,也需要进行手动收集。
同时,系统统计信息也需要手动进行收集,使用GATHER_FIXED_OBJECTS_STATS存储过程(应该在系统具有典型负载的情况下进行收集)。
DBMS_STATS提供了多种功能,以便于我们操作统计信息。如可通过DBMS_STATS.DELETE_TABLE_STATS删除统计信息、也可通过DBMS_STATS.LOCK_TABLE_STATS锁定统计信息等。
注意:使用GATHER_SCHEMA_STATS、GATHER_DATABASE_STATS两种方式收集统计信息时,不会自动对外部表进行统计信息收集(自动收集默认情况不不收集外部表统计信息)。但可通过GATHER_TABLE_STATS对外部表进行统计信息收集。
三、手动收集统计信息
使用DBMS_STATS包进行统计信息收集,不要使用ANALYZE进行收集。
DBMS_STATS可以对整个库、整个用户、表、索引、列进行统计信息收集。DBMS_STATS包常用的存储过程如下:
| Procedure | Collects |
| GATHER_INDEX_STATS | Index statistics |
| GATHER_TABLE_STATS | Table, column, and index statistics |
| GATHER_SCHEMA_STATS | Statistics for all objects in a schema |
| GATHER_DICTIONARY_STATS | Statistics for all dictionary objects |
| GATHER_DATABASE_STATS | Statistics for all objects in a database |