為什么80%的碼農都做不了架構師?>>> ??
大家做過統計的一些存儲過程可能會知道,我們經常有這類表,要先truncate它,執行插入,再在執行相關sql,這就會導致有一個時間誤差,如果在truncate和插入的中間進行了表的分析,這個統計信息是不準確的,也會影響執行計劃:
?
- 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??
SQL> select num_rows,blocks from user_tables; NUM_ROWS BLOCKS
---------- ----------50315 103SQL> 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 103SQL> 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,但是之后就是錄入數據到臨時表
?
SQL> select num_rows,blocks? from user_tables;
? NUM_ROWS???? BLOCKS
---------- ----------
???????? 0????????? 0
SQL> insert into daodao_temp select object_id,object_id from dba_objects;
50315 rows created.
SQL> commit;
Commit complete.
有數據進行入庫:
好了,這個時候已經不會再執行統計信息的存儲過程了(除非第二天的時候),這個時候如果有一個sql執行,就會導致執行計劃可能錯誤了。
這種現象在月初尤其明顯,道理類似的。
我們可以對這類臨時表進行錄入數據的鎖定統計信息:
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.