統計信息是個非常有用的東東,沒有它,SQL優化器就好比巧婦難為無米之炊!良好高效的SQL執行計劃依賴於真實的統計信息。然而在有些情況下,比如對比生產環境與測試環境執行計劃,需要使用生產環境的統計信息。而有時候呢則需要還原Oracle歷史統計信息。本文基於後者即如何還原歷史統計信息來展開,同時描述了11g缺省情況下對於統計信息的調度。
有關統計信息的導入導出可以參考:
1、演示環境
sys@MMBO> select * from v$version where rownum<2; BANNER ----------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production --查看schema HR上對象的最後analyze 的時間(注,為簡化頁面,部分輸出行省略,下同) sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- REGIONS 20130815 18:03:55 LOCATIONS 20130815 18:03:55 DEPARTMENTS 20130815 18:03:56 JOBS 20130815 18:03:56 --創建用於存放導出統計信息的表STATS_TABLE sys@MMBO> exec dbms_stats.create_stat_table('HR', 'STATS_TABLE'); PL/SQL procedure successfully completed. --導出schema HR此時的統計信息 sys@MMBO> exec dbms_stats.export_schema_stats('HR','STATS_TABLE','HR'); PL/SQL procedure successfully completed. -- Author : Leshami -- Blog : http://blog.csdn.net/leshami --此時收集整個schema的統計信息 sys@MMBO> exec dbms_stats.gather_schema_stats('HR'); PL/SQL procedure successfully completed. --收集之後,對象的LAST_ANALYZED變為20140307 sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- STATS_TABLE 20140307 10:26:31 REGIONS 20140307 10:26:30 LOCATIONS 20140307 10:26:30 DEPARTMENTS 20140307 10:26:29
2、統計信息保留的時效性及可用性
--可以保留31天以內統計信息 sys@MMBO> select DBMS_STATS.GET_STATS_HISTORY_RETENTION from dual; GET_STATS_HISTORY_RETENTION --------------------------- 31 --最久的歷史可用統計信息為03-FEB-14 sys@MMBO> select DBMS_STATS.GET_STATS_HISTORY_AVAILABILITY from dual; GET_STATS_HISTORY_AVAILABILITY --------------------------------------------------------------------------- 03-FEB-14 10.28.31.948055000 PM +08:00
3、還原歷史統計信息
--使用下面的過程來還原歷史統計信息,注意以下演示的是還原schema級別的歷史統計信息 sys@MMBO> exec dbms_stats.restore_schema_stats('HR',sysdate-1); PL/SQL procedure successfully completed. --查看還原之後scheme HR上對象的LAST_ANALYZED時間,這個與收集統計信息之前是一致的 --盡管我們指定了sysdate-1,但實際上昨天的歷史統計信息的最後analyzed 也是20130815,也就是說很久沒有analyze過了 sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- STATS_TABLE 20140307 10:26:31 REGIONS 20130815 18:03:55 LOCATIONS 20130815 18:03:55 DEPARTMENTS 20130815 18:03:56 JOBS 20130815 18:03:56 --接下來我們嘗試導入之前備份的統計信息 sys@MMBO> exec dbms_stats.import_schema_stats('HR','STATS_TABLE','HR'); PL/SQL procedure successfully completed. sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- STATS_TABLE 20140307 10:26:31 REGIONS 20130815 18:03:55 LOCATIONS 20130815 18:03:55 DEPARTMENTS 20130815 18:03:56 JOBS 20130815 18:03:56 --再次收集統計信息 sys@MMBO> exec dbms_stats.gather_schema_stats('HR'); PL/SQL procedure successfully completed. --此時統計信息的時間被刷新到10:36 sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- STATS_TABLE 20140307 10:36:48 REGIONS 20140307 10:36:48 LOCATIONS 20140307 10:36:47 --此時我們指點時間點來還原歷史統計信息 sys@MMBO> exec dbms_stats.restore_schema_stats('HR','07-MAR-14 10:26:32AM'); PL/SQL procedure successfully completed. sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- STATS_TABLE 20140307 10:26:31 REGIONS 20140307 10:26:30 LOCATIONS 20140307 10:26:30 --接下來我們直接使用sysdate來還原整個schema sys@MMBO> exec dbms_stats.restore_schema_stats('HR',sysdate); PL/SQL procedure successfully completed. --根據下面的這個查詢可知,使用sysdate參數,缺省的會還原到當天最早收集統計信息的那一次 sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- STATS_TABLE 20140307 10:26:31 REGIONS 20140307 10:26:30 LOCATIONS 20140307 10:26:30 --再次通過指定時間點來進行還原 sys@MMBO> exec dbms_stats.restore_schema_stats('HR','07-MAR-14 10:36:50AM'); PL/SQL procedure successfully completed. --此時統計信息被還原到最新 sys@MMBO> select table_name,last_analyzed from dba_tables where owner='HR'; TABLE_NAME LAST_ANALYZED ------------------------------ ----------------- STATS_TABLE 20140307 10:36:48 REGIONS 20140307 10:36:48 LOCATIONS 20140307 10:36:47
4、調度統計信息(11g)
缺省情況下,Oracle為我們定義了收集統計信息的scheduler,下面列出來在Oracle 11g配置的關於自動收集統計信息的scheduler。 下文調用的SQL腳本來在Oracle 性能診斷一書 sys@MMBO> @dbms_stats_job_11g sys@MMBO> sys@MMBO> SELECT task_name, status 2 FROM dba_autotask_task 3 WHERE client_name = 'auto optimizer stats collection'; TASK_NAME STATUS ----------------- ------- gather_stats_prog ENABLED sys@MMBO> sys@MMBO> PAUSE sys@MMBO> sys@MMBO> SELECT program_action, number_of_arguments, enabled 2 FROM dba_scheduler_programs 3 WHERE owner = 'SYS' 4 AND program_name = 'GATHER_STATS_PROG'; PROGRAM_ACTION NUMBER_OF_ARGUMENTS ENABLED ----------------------------------------- ------------------- ------- dbms_stats.gather_database_stats_job_proc 0 TRUE sys@MMBO> sys@MMBO> PAUSE sys@MMBO> sys@MMBO> SELECT window_group 2 FROM dba_autotask_client 3 WHERE client_name = 'auto optimizer stats collection'; WINDOW_GROUP -------------- ORA$AT_WGRP_OS sys@MMBO> sys@MMBO> PAUSE sys@MMBO> --以下是系統默認的調度頻率 sys@MMBO> SELECT w.window_name, w.repeat_interval, w.duration, w.enabled 2 FROM dba_autotask_window_clients c, dba_scheduler_windows w 3 WHERE c.window_name = w.window_name 4 AND c.optimizer_stats = 'ENABLED'; WINDOW_NAME REPEAT_INTERVAL DURATION ENABLED ---------------- ------------------------------------------ ------------- ------- WEDNESDAY_WINDOW freq=daily;byday=WED;byhour=22;byminute=0; +000 04:00:00 TRUE bysecond=0 SATURDAY_WINDOW freq=daily;byday=SAT;byhour=6;byminute=0; +000 20:00:00 TRUE bysecond=0 THURSDAY_WINDOW freq=daily;byday=THU;byhour=22;byminute=0; +000 04:00:00 TRUE bysecond=0 TUESDAY_WINDOW freq=daily;byday=TUE;byhour=22;byminute=0; +000 04:00:00 TRUE bysecond=0 SUNDAY_WINDOW freq=daily;byday=SUN;byhour=6;byminute=0; +000 20:00:00 TRUE bysecond=0 MONDAY_WINDOW freq=daily;byday=MON;byhour=22;byminute=0; +000 04:00:00 TRUE bysecond=0 FRIDAY_WINDOW freq=daily;byday=FRI;byhour=22;byminute=0; +000 04:00:00 TRUE bysecond=0
更多參考
DML Error Logging 特性
PL/SQL --> 游標
PL/SQL --> 隱式游標(SQL%FOUND)
批量SQL之 FORALL 語句
批量SQL之 BULK COLLECT 子句
PL/SQL 集合的初始化與賦值
PL/SQL 聯合數組與嵌套表
SQL tuning 步驟
高效SQL語句必殺技
父游標、子游標及共享游標
綁定變量及其優缺點
dbms_xplan之display_cursor函數的使用
dbms_xplan之display函數的使用
執行計劃中各字段各模塊描述
使用 EXPLAIN PLAN 獲取SQL語句執行計劃