2015-09-26 125 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過程,看看是否如此。 –