目标对象参数指定要为哪些对象收集对象统计信息。
Ø ownname 指定要处理的模式的名称。这个参数是强制参数。
Ø indname 指定要处理的索引的名称。这个参数是强制参数。
Ø tabname 指定要处理的表的名称。这个参数是强制参数。
Ø partname 指定要处理的分区或者子分区的名称。如果没有指定任何值,则可能会收集所有分区和子分区的对象统计信息,具体取决于granularity参数(见下面)的取值。默认值为NULL。
Ø comp_id 指定要处理的组件的ID。因为组件的ID无法用于收集统计信息,所以会在内部将它转换成一组模式的列表。要想知道对于一个给定的组件都处理了哪些模式,可以使用下面的查询。注意这个查询的输出受多个因素的影响,比如版本和实际安装的组件等。sys和system模式独立于此参数,总是会被处理。如果指定了非法值,则不会返回错误信息,并且sys和system模式会正常进行处理。通过使用默认值NULL,所有的组件都会被处理:
select u.username as schema_name, r.cid as
comp_id, r.cname as comp_name
from dba_users u,
(select schema#, cid, cname
from sys.registry$
where status in (1, 3, 5)
and namespace = 'SERVER'
union all
select s.schema#, s.cid, cname
from sys.registry$ r, sys.registry$schemas s
where r.status in (1, 3, 5)
and r.namespace = 'SERVER'
and r.cid = s.cid) r
where u.user_id = r.schema#
order by r.cid, u.username;
①遗憾的是,Oracle并不会使所有必需的信息都在数据字典中可见。所以,这个查询是基于内部表的。系统权限select any dictionary能够提供对必要的表的访问权限。
Ø granularity 指定会在哪个级别处理已分区对象的统计信息。这个参数接受表8-4中的值。默认值是auto(默认值可以修改)。
表8-4
granularity参数接受的参数
值 |
含 义 |
all |
收集表/索引、分区以及子分区的统计信息 |
auto |
收集表/索引和分区的统计信息。只有当表使用列表或范围分区时才会收集子分区的统计信息 |
global |
只收集表/索引的统计信息 |
global and partition |
收集表/索引和分区的统计信息 |
approx_global and partition |
与global and |
partition |
只收集分区的统计信息 |
subpartition |
只收集子分区的统计信息 |
Ø cascade 指定是否处理索引的数据。这个参数接受的值为TRUE、FLASE以及dbms_stats.auto_cascade。后者是一个设置为NULL的常量值,让数据库引擎来决定是否收集索引统计信息。默认值是dbms_stats.auto_cascade(默认值可以修改)。
Ø gather_fixed 指定是否为固定表收集对象统计信息。这个参数接受的值为TRUE和FALSE。 默认值是FALSE。
Ø gather_sys 指定是否收集sys模式下的数据。这个参数接受的值为TRUE和FALSE。默认值是FALSE。
Ø gather_temp 指定是否收集临时表的数据。这个参数接受的值为TRUE和FALSE。默认值是FALSE。
Ø options 指定有哪些对象以及是否收集它们。这个参数接受的值在表8-5中列出。但是,当这个参数与gather_table_stats存储过程一起使用时,只有gather和gather auto受支持。默认值是gather。
表8-5 options参数接受的值
值 |
含 义 |
gather |
处理所有对象 |
gather auto |
让存储过程不仅决定要处理哪些对象而且还要决定如何去处理这些对象。当在 gather_table_stats存储过程中使用参数的值为not时,除了ownname、objlist. stattab、statid以及statown以外的所有参数都会被忽略 |
gather stale |
只有包含过期对象统计信息的对象会被处理。注意,不会将没有对象统计信息的对象视为过期的 |
gather empty |
只有没有对象统计信息的对象才会被处理 |
list auto |
对于所列举的对象会按照gather |
list stale |
对于所列举的对象会按照gather |
list empty |
对于所列举的对象会按照gather |
Ø objlist根据options参数取值的不同,返回已经处理过的或者即将要处理的对象的列表。这是一个基于dbms_stats包中定义的类型的输出参数。举个例子,下面的PL/SQL代码块展示了如何显示处理过的对象列表:
DECLARE
l_objlist dbms_stats.objecttab;
l_index PLS_INTEGER;
BEGIN
dbms_stats.gather_schema_stats(ownname => 'HR', objlist =>
l_objlist);
l_index := l_objlist.FIRST;
WHILE l_index IS NOT NULL Loop
dbms_output.put_line(l_objlist(l_index).ownname || '.');
dbms_output.put_line(l_objlist(l_index).ojbname);
l_index := l_objlist.next(l_index);
END
LOOP;
END;
/
Ø force指定是否覆盖已锁定的统计信息。如果将这个参数设置为FALSE,而一个用来处理一张单独的表或者索引的存储过程正在处理锁定的统计信息,那么就会引发一个错误(ORA-20005)。这个参数接受的值为TRUE和FALSE。
Ø obj_filter_list 用于指定只为那些至少满足作为参数传递的其中一个过滤条件的对象收集统计信息。它基于dbms_stats包自身中定义的objecttab类型,并且只在11.1及以后的版本中才可用。下面的PL/SQL代码块展示了如何为HR模式下的所有表和SH模式下的所有表以及使用字母C开头的对象收集统计信息:
DECLARE
l_filter dbms_stats.objecttab := dbms_stats.objecttab();
BEGIN
l_filter.extend(2);
l_filter(1).ownname := 'HR';
l_filter(2).ownname := 'SH';
l_filter(2).objname := 'C%';
dbms_stats.gather_database_stats(obj_filter_list => l_filter,
options => 'gather');
END;
/
对象统计信息的过期
为识别出对象统计信息是否过期,数据库引擎对每张表上通过SQL语句修改的数据行的数量进行计数(约计)。计数的结果可以通过数据字典视图all_tab_modifications、dba_tab_modifications(这个视图仅从11.2版本开始才可用)、user_tab_modifications来查看,还可以通过12.1的多租户环境下的cdb_tab_modifications视图来查看。下面的查询是一个样例:
select inserts,updates,deletes,truncated
from user_tab_modifications
where table_name='T';
根据这个信息,dbms_stats包能够确定与某个对象关联的对象统计信息是否过期。在10.2版本中,必须有至少10%的数据行被修改了才会认为对象统计信息过期。从11.1版本开始,可以通过stale_percent首选项来配置这个阈值。默认值是10%。
要小心,因为在10.2.0.5、11.2.0.1以及11.2.0.2版本中,通过DataPump导入到一张空表中的数据的计数和正常插入的数据相比是不正确的。因此,在导入之后,会认为对象统计信息过期。
计数是由数据库端的初始化参数statistics_level控制的。如果这个参数设置为typical(也就是默认值)或者all,那么计数为启用状态。