對於常常須要truncate的表進行固定統計信息

你們作過統計的一些存儲過程可能會知道,咱們常常有這類表,要先truncate它,執行插入,再在執行相關sql,這就會致使有一個時間偏差,若是在truncate和插入的中間進行了表的分析,這個統計信息是不許確的,也會影響執行計劃: sql

 

  1. SQL> select num_rows,blocks  from user_tables;   
  2.   
  3.   NUM_ROWS     BLOCKS  
  4. ---------- ----------  
  5.      50315        103  
  6.   
  7. SQL> turncate table daodao_temp;  
  8. SP2-0734: unknown command beginning "turncate t..." - rest of line ignored.  
  9. SQL> truncate table daodao_temp;  
  10.   
  11. Table truncated.  
  12.   
  13. SQL> select num_rows,blocks  from user_tables;   
  14.   
  15.   NUM_ROWS     BLOCKS  
  16. ---------- ----------  
  17.      50315        103  
  18.   
  19. SQL> execute dbms_stats.gather_table_stats(user,'DAODAO_TEMP');  
  20.   
  21. PL/SQL procedure successfully completed.  
  22.   
  23. SQL> select num_rows,blocks  from user_tables;   
  24.   
  25.   NUM_ROWS     BLOCKS  
  26. ---------- ----------  
  27.          0          0  
SQL> select num_rows,blocks  from user_tables; 

  NUM_ROWS     BLOCKS
---------- ----------
     50315        103

SQL> turncate table daodao_temp;
SP2-0734: unknown command beginning "turncate t..." - rest of line ignored.
SQL> truncate table daodao_temp;

Table truncated.

SQL> select num_rows,blocks  from user_tables; 

  NUM_ROWS     BLOCKS
---------- ----------
     50315        103

SQL> execute dbms_stats.gather_table_stats(user,'DAODAO_TEMP');

PL/SQL procedure successfully completed.

SQL> select num_rows,blocks  from user_tables; 

  NUM_ROWS     BLOCKS
---------- ----------
         0          0


 

 --這裏是關鍵點,咱們有個按天分析的job,若是這個時候分析了這個數據,會認爲數據爲0,可是以後就是錄入數據到臨時表 spa

 

SQL> select num_rows,blocks  from user_tables; .net

  NUM_ROWS     BLOCKS
---------- ----------
         0          0 rest


SQL> insert into daodao_temp select object_id,object_id from dba_objects; code

50315 rows created. blog

SQL> commit; get

Commit complete. it

有數據進行入庫: table

好了,這個時候已經不會再執行統計信息的存儲過程了(除非次日的時候),這個時候若是有一個sql執行,就會致使執行計劃可能錯誤了。 class

這種現象在月初尤爲明顯,道理相似的。

咱們能夠對這類臨時表進行錄入數據的鎖定統計信息:

SQL> execute dbms_stats.gather_table_stats(user,'DAODAO_TEMP');

SQL> select num_rows,blocks  from user_tables;

  NUM_ROWS     BLOCKS
---------- ----------
     50315        103

SQL> execute DBMS_STATS.LOCK_TABLE_STATS(user,'DAODAO_TEMP');

PL/SQL procedure successfully completed.

SQL> TRUNCATE TABLE DAODAO_TEMP;

Table truncated.

SQL> execute dbms_stats.gather_table_stats(user,'DAODAO_TEMP');
BEGIN dbms_stats.gather_table_stats(user,'DAODAO_TEMP'); END;

*
ERROR at line 1:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at "SYS.DBMS_STATS", line 13056
ORA-06512: at "SYS.DBMS_STATS", line 13076
ORA-06512: at line 1

這樣蒐集統計信息的時候就不會蒐集了,相關數據字典能夠查詢這個:

SQL> select stattype_locked from user_tab_statistics where table_name ='DAODAO_TEMP';

STATT
-----
ALL

all表示鎖定了 ,空表示沒有鎖定:

若是須要解鎖,能夠執行以下:

SQL> execute dbms_stats.unlock_table_stats(user,'DAODAO_TEMP');

PL/SQL procedure successfully completed.

相關文章
相關標籤/搜索