RESTORE_TABLE_STATS Procedure
This procedure restores statistics of a table as of a specified timestamp (as_of_timestamp). The procedure will restore statistics of associated indexes and columns as well. If the table statistics were locked at the specified timestamp the procedure will lock the statistics. The procedure will not restore user defined statistics.
Syntax
DBMS_STATS.RESTORE_TABLE_STATS (
ownname VARCHAR2,
tabname VARCHAR2,
as_of_timestamp TIMESTAMP WITH TIME ZONE,
restore_cluster_index BOOLEAN DEFAULT FALSE,
force BOOLEAN DEFAULT FALSE,
no_invalidate BOOLEAN DEFAULT to_no_invalidate_type
(GET_PARAM('NO_INVALIDATE')));
Parameters
Table 103-64 RESTORE_TABLE_STATS Procedure Parameters
Parameter
|
Description
|
ownname
|
The schema of the table for which the statistics are to be restored
|
tabname
|
The table name
|
as_of_timestamp
|
The timestamp to which to restore statistics
|
restore_cluster_index
|
If the table is part of a cluster, restore statistics of the cluster index if set to TRUE
|
force
|
Restores statistics even if the table statistics are locked. If the table statistics were not locked at the specified timestamp, it unlocks the statistics.
|
no_invalidate
|
Does not invalidate the dependent cursors if set to TRUE. The procedure invalidates the dependent cursors immediately if set to FALSE. Use DBMS_STATS.AUTO_INVALIDATE. to have Oracle decide when to invalidate dependent cursors. This is the default. The default can be changed using the .
|
Exceptions
ORA-20000: Object does not exist or insufficient privileges.
ORA-20001: Invalid or inconsistent values.
ORA-20006: Unable to restore statistics, statistics history not available.
上面as_of_timestamp選項,指定把統計資訊還原到哪個時間點,資料型別為timestamp with time zone
SQL> alter session set nls_timestamp_tz_format='yyyy-mm-dd hh24:mi:ss.ff';
Session altered.
SQL> select to_timestamp_tz('2014-08-07 00:00:00.00','yyyy-mm-dd hh24:mi:ss.ff') from dual;
TO_TIMESTAMP_TZ('2014-08-0700:00:00.00','YYYY-MM-DDHH24:MI:SS.FF')
---------------------------------------------------------------------------
2014-08-07 00:00:00.000000000
SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALY STATT
------------------------------ ------------ ---------- --- ---------- -----
T_STAT TABLE
SQL> exec dbms_stats.restore_table_stats(user,'t_stat',to_timestamp_tz('2014-08-07 00:00:00.00','yyyy-mm-dd hh24:mi:ss.ff'),false,true,true);
PL/SQL procedure successfully completed.
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
再次手工收集表統計資訊,為了測試restore_table_stats的功能
SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
由下可以表的統計資訊是2014-08-07 09:02:26產生的
SQL> col table_name for a30
SQL> set linesize 300
SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 101073 NO 2014-08-07 09:02:26
SQL>
還原表的統計資訊到上述
2014-08-07 09:02:26這個時間之前
SQL> exec dbms_stats.restore_table_stats(user,'t_stat',to_timestamp_tz('2014-08-07 09:00:00.00','yyyy-mm-dd hh24:mi:ss.ff'),false,true,true);
PL/SQL procedure successfully completed.
表的統計資訊已經不存在了,因為這個時間點表沒有產生統計資訊呢
SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE
SQL> select table_name,num_rows,last_analyzed from user_tables where lower(table_name)='t_stat';
TABLE_NAME NUM_ROWS LAST_ANALYZED
------------------------------ ---------- -------------------
T_STAT
繼續測試在不同時間點產生表的資料,然後恢復到到不同的時間點,檢視錶統計資訊的差異
SQL> set time on
09:09:25 SQL> truncate table t_stat;
Table truncated.
09:09:41 SQL> insert into t_stat values(1,1);
1 row created.
09:09:52 SQL> select systimestamp from dual;
SYSTIMESTAMP
---------------------------------------------------------------------------
2014-08-07 09:11:19.482998
第一次收集統計資訊
09:13:45 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:13:46 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 1 NO 2014-08-07 09:13:46
第2次收集統計資訊
09:16:17 SQL> insert into t_stat values(2,2);
1 row created.
09:16:26 SQL> commit;
Commit complete.
09:16:27 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:16:30 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 2 NO 2014-08-07 09:16:30
第3次收集統計資訊
09:16:57 SQL> insert into t_stat values(3,3);
1 row created.
09:17:05 SQL> commit;
Commit complete.
09:17:06 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:17:09 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 3 NO 2014-08-07 09:17:09
09:17:12 SQL>
恢復表的統計資訊到第3次收集統計資訊之前
09:21:58 SQL> exec dbms_stats.restore_table_stats(user,'t_stat',to_timestamp_tz('2014-08-07 09:16:31.00','yyyy-mm-dd hh24:mi:ss.ff'),false,true,true);
PL/SQL procedure successfully completed.
表t_stat統計資訊正好恢復到第2次收集表的統計資訊
09:23:21 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 2 NO 2014-08-07 09:16:30
如果上次恢復到指定的時間點後,再次恢復到另一個時間點,就不會成功了
09:24:18 SQL> exec dbms_stats.restore_table_stats(user,'t_stat',to_timestamp_tz('2014-08-07 09:17:09.00','yyyy-mm-dd hh24:mi:ss.ff'),false,true,true);
PL/SQL procedure successfully completed.
09:27:29 SQL>
09:27:30 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 2 NO 2014-08-07 09:16:30
小結:
1,restore_table_stats可以靈活把表的統計資訊恢復到不同的時間點
2, restsore_table_stats只可以使用1次,再次恢復雖不會報錯,但還是保持第一次恢復後的時間點
5,測試如果表發生了ddl,上述的restore_table_stats會採取如何的表現呢?
馬上最新收集表的統計資訊
09:37:45 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:39:04 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 3 NO 2014-08-07 09:39:03
表新增c列
09:42:39 SQL> alter table t_stat add c int;
Table altered.
09:43:31 SQL> insert into t_stat values(4,4,4);
1 row created.
09:43:35 SQL> commit;
Commit complete.
09:45:25 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:45:30 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 4 NO 2014-08-07 09:45:30
46:42 SQL> exec dbms_stats.restore_table_stats(user,'t_stat',to_timestamp_tz('2014-08-07 09:39:03.00','yyyy-mm-dd hh24:mi:ss.ff'),false,true,true);
PL/SQL procedure successfully completed.
發現恢復沒有報錯,但是恢復到最新收集統計資訊之前的哪個時間點了
09:47:32 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 2 NO 2014-08-07 09:16:30
為了確認ddl對於restore_table_stats的影響是否如上述所言,再次進行測試
09:54:28 SQL> drop table t_stat purge;
Table dropped.
09:54:41 SQL> create table t_stat(a int,b int);
Table created.
09:54:50 SQL> insert into t_stat values(1,1);
1 row created.
09:54:58 SQL> commit;
Commit complete.
第1次收集表統計資訊
09:54:59 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:55:03 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 1 NO 2014-08-07 09:55:03
09:55:11 SQL> insert into t_stat values(2,2);
1 row created.
09:56:09 SQL> commit;
Commit complete.
第2次收集表統計資訊
09:56:13 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:56:16 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 2 NO 2014-08-07 09:56:16
發生ddl操作
09:56:55 SQL> alter table t_stat add c int;
Table altered.
09:57:02 SQL> insert into t_stat values(3,3,3);
1 row created.
09:57:15 SQL> commit;
Commit complete.
第3次收集表統計資訊
09:57:17 SQL> exec dbms_stats.gather_table_stats(user,'t_stat',cascade=>true);
PL/SQL procedure successfully completed.
09:57:19 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 3 NO 2014-08-07 09:57:19
運用restore_table_stats恢復到ddl之前的時間點
09:57:21 SQL> exec dbms_stats.restore_table_stats(user,'t_stat',to_timestamp_tz('2014-08-07 09:56:17.00','yyyy-mm-dd hh24:mi:ss.ff'),false,true,true);
PL/SQL procedure successfully completed.
可以恢復到ddl之前的時間點
09:59:10 SQL> select table_name,object_type,num_rows,stale_stats,last_analyzed,stattype_locked from user_tab_statistics where lower(table_name)='t_stat';
TABLE_NAME OBJECT_TYPE NUM_ROWS STA LAST_ANALYZED STATT
------------------------------ ------------ ---------- --- ------------------- -----
T_STAT TABLE 2 NO 2014-08-07 09:56:16
小結:ddl操作仍可以正常使用restore_table_stats把表的統計資訊恢復到你想恢復的哪個時間點