oracle 处理分区对象统计信息
挑战
dbms_stats包使用两种主要的方式为分区的表和索引收集对象统计信息。
Ø 在对象、分区以及子分区级别上通过在每个级别上分别执行的查询来收集对象统计信息。
Ø 只在物理层面(可能是分区级别也可能是子分区级别)收集对象统计信息,并使用其结果来推算出其他级别的对象统计信息。
下面是这两种方式的两个关键区别。
Ø 总的来说,第一种收集对象统计信息的方式需要的时间和资源要高很多。实际上,在表/索引级别收集对象统计信息时,必须要访问所有的段。同样的事情也会发生在子分区对象的分区级别。例如,一张包含多年数据的按星期分区的表。如果一个分区发生了变化,那么必须访问所有分区才能更新表/索引级别统计信息。甚至在只有一个分区的数据被修改了的情况下,也必须访问所有分区。
Ø 第二种方式消耗的资源则要少很多,但是这种方式只能在物理级别生成准确的统计信息。这是因为它无法从底层的分区和子分区推算出不重复值的数量和直方图。顺便说一下,其他所有的统计信息都可以推算出来。
通过第一种方式收集的对象统计信息叫作全局统计信息。
通过第二种方式收集的统计信息叫作推算统计信息(有时也称作聚合统计信息)。
要辨别收集的是哪种类型,可以检查表8-2中列举的数据字典视图中global_stats列值是YES还是NO。只要可能,dbms_stats包就会收集全局统计信息。dbms_stats包只会在某些情况下收集推算统计信息,例如,收集的粒度被明确地限制在子分区级别并且在分区以及表/索引级别没有可用的对象统计信息时。
接下来的例子基于脚本global_stats.sql生成的输出,展示了这样的案例:对于一张按范围分区并按照hash进行子分区的表,其推算统计信息并不准确。注意,不仅表和分区级别的不重复值数量有误,global_stats列也被设置为NO。
Ø 在一张没有对象统计信息的表上执行子分区级别的收集(注意,没有涉及采样):
BEGIN
dbms_stats.delete_table_stats(ownname => user,