增量统计信息
正如上一节中描述的那样,收集全局统计信息有优点也有缺点。主要的优点体现在表级别的对象统计信息的准确性上,如果使用了子分区,这个优点同样体现在分区级别。主要的缺点体现在收集它们所需要的资源和时间上。
增量统计信息的目标是在降低收集对象统计信息所需时间和资源的前提下提供相同的准确性。这怎么可能呢?其关键思路是在分区级别收集对象统计信息期间,利用存储在数据字典中的额外信息(称作概要信息),在表级别精确地推算对象统计信息。
要想从增量统计信息中获益必须首先满足以下要求。
Ø 正在运行的是11.1或之后的版本。
Ø 对于正在处理的表,其incremental首选项设置为TRUE(默认值是FALSE):
BEGIN
dbms_stats.set_table_prefs(ownname => user,
tabname => 't',
pname => 'incremental',
pvalue => 'TRUE');
END;
/
Ø 对于正在处理的表,其publish首选项设置为TRUE(默认值)。
Ø 对于正在处理的表,将参数estimate_percent设置为dbms_stats.auto_sample_size(默认值)。
Ø 在sysaux表空间中有可用剩余空间。
收集过程本身还是按照通常的方式进行,例如,通过对dbms_stats包的gather_table_stats存储过程的调用。唯一需要小心应对的是,要利用增量统计信息,必须在分区级别呈现概要信息。因此,设置完incremental首选项后,你必须在所有分区上收集新的对象统计信息。你可以认为在所有分区上收集新的对象统计信息的操作是最终启用增量统计信息的那个操作。也就是说,只满足上面列举的要求是不够的。
一旦所有的概要信息都就位了,dbms_stats包就会使用其监测信息来了解哪个分区(或子分区)被修改了,从而需要新的对象统计信息。因此,当使用增量统计信息时,不应该去瞄准被修改的分区(或子分区),而是应该让dbms_stats包自己找出它需要做的事情。下面的例子基于脚本incremental_stats.sql,就验证了这一点(仔细看一下last_analyzed时间戳来确定在哪些对象上收集了统计信息):
SELECT object_type || ' ' || nvl(subpartition_name,
partition_name) AS object,
object_type, num_rows, blocks, avg_row_len,
to_char(last_analyzed, 'HH24:MI:SS') AS last_analyzed
FROM user_tab_statistics
WHERE table_name = 'T'
ORDER BY partition_name, subpartition_name;
INSERT INTO t SELECT * FROM t SUBPARTITION
(q1_sp1);
COMMIT;
BEGIN
dbms_lock.sleep(2);
dbms_stats.gather_table_stats(ownname
=> user,
tabname => 't',
granularity
=> 'all');
END;
/
SELECT object_type || ' ' ||
nvl(subpartition_name, partition_name) AS object,
object_type, num_rows, blocks, avg_row_len,
to_char(last_analyzed, 'HH24:MI:SS') AS last_analyzed
FROM user_tab_statistics
WHERE table_name = 'T'
ORDER BY partition_name, subpartition_name;
P227
如本例所示,与分区(或子分区)关联的对象统计信息在经历任何修改后都会被视为陈旧的。从12.1版本开始,有一个首选项incremental_staleness,你可以通过它控制这种行为。通过默认值NULL,这种行为与之前的版本表现一致(任何修改都会使一个分区变陈旧)。
如果将值设置为use_stale_percent,只有当修改的数量超过通过stale_percent首选项设置的阈值后,与分区(或子分区)关联的对象统计信息才会被认为是陈旧的。此外,通过值use_locked_stats,可以规定与拥有锁定的统计信息的分区(或子分区)关联的对象统计信息永不过期。注意可以同时启用use_stale_percent和use_locked_stats。
下面是一个例子:
BEGIN
dbms_stats.set_table_prefs(ownname => user,
tabname => 't',
pname => 'incremental_staleness',
pvalue => 'use_stale_percent, use_locked_stats');
END;
/
仅在12.1版本中,dbms_stats包可以在非分区表上创建概要信息(为此,必须在表上设置nincremental_leveln首选项)。结果,仅在12.1版本中,分区交换才可以利用增量统计信息。
提示 Oracle
Support文档How To
Collect Statistics On Partitioned Table in 10g and 11g(1417133. 1)中提供了一个与增量统计信息有关的最重要的Bug和补丁列表。查看这篇文章来了解你正在运行的版本是否需要特别的关注,并进一步检查第一篇文章引用的其他文章。