2015-09-26 130 views
1

每次ETL作业完成后,我必须收集每个表(包括其索引空间)的实际使用空间以及行数。Oracle计算实际使用大小和统计信息收集

user_segments和user_extents中的字节列仅指示分配的空间。所以我使用以下来获得每个表的大小:

Dbms_Space.object_space_usage (
    object_owner => v_owner, 
    object_name  => c.name, 
    object_type  => c.typ, 
    sample_control => NULL, 
    space_used  => v_space_used_out, 
    space_allocated => v_space_allocated_out, 
    chain_pcent  => v_chain_pcent_out); 
    v_space_used := v_space_used+v_space_used_out; 
    v_space_allocated := v_space_allocated+v_space_allocated_out; 

循环遍历每个索引和表本身。

我的问题是在我运行上面的代码之前是否需要运行?

EXEC DBMS_STATS.GATHER_TABLE_STATS(v_owner,v_table_name); 

为什么和/或为什么不?

感谢,

+0

看起来这将是很容易测试。创建一个表,插入行,运行Dbms_Space.object_space_usage,看看它告诉你什么。在运行gather_table_stats之后,它会改变吗? –

回答

3

这是没有必要运行EXEC DBMS_STATS.GATHER_TABLE_STATS(v_owner,v_table_name)提前运行DBMS_SPACE.OBJECT_SPACE_USAGE

我跑Dbms_Space.object_space_usage的,得到的结果。然后将大量数据插入表中,并再次运行Dbms_Space.object_space_usage。

结果已更新为新的较大值,但未运行GATHER_TABLE_STATS。

我们从Oracle DBMS_SPACE文档中得知这个软件包需要分析权限。但是,仅在表上运行OBJECT_SPACE_USAGE,不会更新all_tables的last_analyzed列。

因此,从观察结果来看,DBMS_SPACE.OBJECT_SPACE_USAGE似乎对表格进行了自己的分析,得到了正确的空间使用情况。它不依赖由DBMS_STATS收集的更新统计信息,也不会更新统计信息。

只是进一步证明了这一点:

SQL> EXEC DBMS_STATS.delete_table_stats('SOMEOWNER','SOMETABLE'); 

PL/SQL procedure successfully completed. 


SELECT LAST_ANALYZED 
FROM ALL_TABLES 
WHERE OWNER = 'SOMEOWNER' AND TABLE_NAME = 'SOMETABLE'; 

LAST_ANALYZED 
------------------ 


SQL> 
DECLARE 
su NUMBER; 
sa NUMBER; 
cp NUMBER; 
BEGIN 
    dbms_space.object_space_usage('SOMEOWNER', 'SOMETABLE', 'TABLE', 
    NULL, su, sa, cp); 
    dbms_output.put_line('Space Used: ' || TO_CHAR(su)); 
    dbms_output.put_line('Space Allocated: ' || TO_CHAR(sa)); 
    dbms_output.put_line('Chained Percentage: ' || TO_CHAR(cp)); 
    END; 
/

Space Used: 1055374677 
Space Allocated: 1073741824 
Chained Percentage: 0 
+0

精彩的回答!对此,我真的非常感激。 – Shawn

+0

根据返回的值的类型,我猜测它根本没有访问表来完成此分析,它只是读取表格段的段空间管理元数据。通过将表的表空间脱机并运行DBMS_Space过程,看看是否如此。 –