Oracle 各种收集统计信息的方法

查看某个表的统计信息
alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'; 
select t.TABLE_NAME,t.NUM_ROWS,t.BLOCKS,t.LAST_ANALYZED from user_tables t where table_name in ('T1','T2');
查看某个表上索引的统计信息
select table_name,index_name,t.blevel,t.num_rows,t.leaf_blocks,t.last_analyzed from user_indexes t where table_name in ('T1','T2');  
oracle会在一个固定的时间将数据库里的表和索引的相关统计信息进行收集,默认选择周一到周五晚上10点,持续收集4小时,和周六周日早上6点,持续收集20小时。
oracle可以专门对表的记录变化量进行管理,当某表一天记录变化量没有超过指定的阀值时,oracle就不会对该表进行统计信息收集。

修改统计信息自动收集时间
set linesize 200  
col REPEAT_INTERVAL for a60  
col DURATION for a30  
select t1.window_name,t1.repeat_interval,t1.duration from dba_scheduler_windows t1,dba_scheduler_wingroup_members t2  
where t1.window_name=t2.window_name and t2.window_group_name in ('MAINTENANCE_WINDOW_GROUP','BSLN_MAINTAIN_STATS_SCHED');  
  
WINDOW_NAME        REPEAT_INTERVAL                                              DURATION  
------------------ ------------------------------------------------------------ ---------------  
MONDAY_WINDOW      freq=daily;byday=MON;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
TUESDAY_WINDOW     freq=daily;byday=TUE;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
WEDNESDAY_WINDOW   freq=daily;byday=WED;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
THURSDAY_WINDOW    freq=daily;byday=THU;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
FRIDAY_WINDOW      freq=daily;byday=FRI;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
SATURDAY_WINDOW    freq=daily;byday=SAT;byhour=6;byminute=0; bysecond=0         +000 20:00:00  
SUNDAY_WINDOW      freq=daily;byday=SUN;byhour=6;byminute=0; bysecond=0         +000 20:00:00  

关闭自动统计信息收集  
BEGIN  
  DBMS_SCHEDULER.DISABLE(  
  name => '"SYS"."SATURDAY_WINDOW"',  
  force => TRUE);  
END;  
/  
  
  
修改自动统计信息持续时间  
BEGIN  
  DBMS_SCHEDULER.SET_ATTRIBUTE(  
  name => '"SYS"."SATURDAY_WINDOW"',  
  attribute => 'DURATION',  
  value => numtodsinterval(240,'minute'));  
END;    
/  
  
修改自动统计信息开始时间  
BEGIN  
  DBMS_SCHEDULER.SET_ATTRIBUTE(  
  name => '"SYS"."SATURDAY_WINDOW"',  
  attribute => 'REPEAT_INTERVAL',  
  value => 'freq=daily;byday=SAT;byhour=22;byminute=0; bysecond=0 ');  
END;  
/  
  
开启自动统计信息收集  
BEGIN  
  DBMS_SCHEDULER.ENABLE(  
  name => '"SYS"."SATURDAY_WINDOW"');  
END;  
/  

set linesize 200  
col REPEAT_INTERVAL for a60  
col DURATION for a30  
select t1.window_name,t1.repeat_interval,t1.duration from dba_scheduler_windows t1,dba_scheduler_wingroup_members t2  
where t1.window_name=t2.window_name and t2.window_group_name in ('MAINTENANCE_WINDOW_GROUP','BSLN_MAINTAIN_STATS_SCHED');  
  
WINDOW_NAME       REPEAT_INTERVAL                                              DURATION  
----------------- ------------------------------------------------------------ --------------  
MONDAY_WINDOW     freq=daily;byday=MON;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
TUESDAY_WINDOW    freq=daily;byday=TUE;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
WEDNESDAY_WINDOW  freq=daily;byday=WED;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
THURSDAY_WINDOW   freq=daily;byday=THU;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
FRIDAY_WINDOW     freq=daily;byday=FRI;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
SATURDAY_WINDOW   freq=daily;byday=SAT;byhour=22;byminute=0; bysecond=0        +000 04:00:00  
SUNDAY_WINDOW     freq=daily;byday=SUN;byhour=6;byminute=0; bysecond=0         +000 20:00:00  
  
7 rows selected. 

手动收集统计信息
使用dbms_stats程序包手动收集统计信息
收集表统计信息
exec dbms_stats.gather_table_stats(ownname => 'USER',tabname => 'TEST',estimate_percent => 10,method_opt=> 'for all indexed columns');   
exec dbms_stats.gather_table_stats(ownname => 'USER',tabname => 'TAB_NAME',CASCADE=>TURE);  
收集分区表的某个分区统计信息
exec dbms_stats.gather_table_stats(ownname => 'USER',tabname => 'RANGE_PART_TAB',partname => 'p_201312',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE);  
收集索引统计信息
exec dbms_stats.gather_index_stats(ownname => 'USER',indname => 'IDX_OBJECT_ID',estimate_percent => '10',degree => '4');  
收集表和索引统计信息 
exec dbms_stats.gather_table_stats(ownname => 'USER',tabname => 'TEST',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE);  
收集某个用户的统计信息
exec dbms_stats.gather_schema_stats(ownname=>'CS',estimate_percent=>10,degree=>8,cascade=>true,granularity=>'ALL');  
收集整个数据库的统计信息
exec dbms_stats.gather_database_stats(estimate_percent=>10,degree=>8,cascade=>true,granularity=>'ALL');  
关于dbms_stats中参数的解释,具体参考官方文档:
http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_stats.htm#ARPLS68582
ownname: USER_NAME  
tabname: TABLE_NAME  
partname: 分区表的某个分区名  
estimate_percent: 采样百分比,有效范围为[0.000001,100]  
block_sample:使用随机块采样代替随机行采样  
method_opt:  
cascade:是否收集此表索引的统计信息  
degree:并行处理的cpu数量  
granularity: 统计数据的收集,'ALL' - 收集所有(子分区,分区和全局)统计信息  

动态采集统计信息
对于新创建的表,当访问此表时,oracle会动态的收集这个表的相关信息,等到晚上10点,再将其收集到数据字典中。

SQL> set autotrace off   
SQL> create table t_sample as select * from dba_objects;    
Table created.   
SQL> create index idx_t_sample_objid on t_sample(object_id);   
Index created.  
新建的表,查不到统计信息
SQL> select num_rows, blocks, last_analyzed from user_tables where table_name = 'T_SAMPLE';  
  
  NUM_ROWS     BLOCKS LAST_ANAL  
---------- ---------- ---------  

SQL> set autotrace traceonly  
SQL> set linesize 1000  
SQL> select  * from t_sample where object_id=20;  
Execution Plan  
----------------------------------------------------------  
Plan hash value: 1453182238  
  
--------------------------------------------------------------------------------------------------  
| Id  | Operation                   | Name               | Rows  | Bytes | Cost (%CPU)| Time     |  
--------------------------------------------------------------------------------------------------  
|   0 | SELECT STATEMENT            |                    |     1 |   207 |     2   (0)| 00:00:01 |  
|   1 |  TABLE ACCESS BY INDEX ROWID| T_SAMPLE           |     1 |   207 |     2   (0)| 00:00:01 |  
|*  2 |   INDEX RANGE SCAN          | IDX_T_SAMPLE_OBJID |     1 |       |     1   (0)| 00:00:01 |  
--------------------------------------------------------------------------------------------------  
  
Predicate Information (identified by operation id):  
---------------------------------------------------  
  
   2 - access("OBJECT_ID"=20)  
  
Note  
-----  
   - dynamic sampling used for this statement (level=2)  
  
  
Statistics  
----------------------------------------------------------  
         24  recursive calls  
          0  db block gets  
         93  consistent gets  
          1  physical reads  
          0  redo size  
       1608  bytes sent via SQL*Net to client  
        523  bytes received via SQL*Net from client  
          2  SQL*Net roundtrips to/from client  
          0  sorts (memory)  
          0  sorts (disk)  
          1  rows processed  

- dynamic sampling used for this statement (level=2) 表示动态采样,但是不记录数据字典,除非手动收集表的统计信息。
[html] view plain copy
SQL> select num_rows, blocks, last_analyzed from user_tables where table_name = 'T_SAMPLE';  
  
  NUM_ROWS     BLOCKS LAST_ANAL  
---------- ---------- ---------  
  
  
SQL> 

----------------------------------------------------------------------------------------------------------------------------------------全库收集
exec dbms_stats.gather_database_stats(estimate_percent=>10,degree=>8,cascade=>true,granularity=>'ALL');

schema收集
exec dbms_stats.gather_schema_stats(ownname=>'SE',estimate_percent=>10,degree=>8,cascade=>true,granularity=>'ALL');

Table收集
exec dbms_stats.gather_table_stats(ownname=>'DW_HW_CHCH',tabname=>'表名',estimate_percent=>10,degree=>8,cascade=>true,granularity=>'ALL');

分区收集
exec dbms_stats.gather_table_stats(ownname=>'DW_HW_CHCH',tabname=>'表名',partname='分区名',estimate_percent=5,degree=>8,cascade=>true,granularity=>'PARTITION',method_opt>'FOR ALL INDEXED COLUMNS');

数据字典收集
exec dbms_stats.gather_dictionary_stats (estimate_percent=>100,degree=>8,cascade=>true,granularity=>'ALL');

动态性能表统计信息
exec dbms_stats.gather_fixed_objects_stats;

硬件统计信息收集
--典型业务开始前
exec dbms_stats.gather_system_stats('START');
--典型业务结束后
exec dbms_stats.gather_system_stats('STOP');


将一个表的统计信息锁住,以防止错误的统计信息将此正确的信息覆盖掉时需要用到LOCK_TABLE_STATS包
--对于有些表或者用户的数据基本不怎么发生变化,如果每次收集时也将其收集一遍浪费资源,因此可以将这些表或者用户进行统计信息采集的锁定
exec dbms_stats.lock_table_stats('owner name','table name');

exec dbms_stats.lock_schema_stats ('schema name');
--通过unlock_table_stats   unlock_schema_stats 可以解锁


select
column_name,
num_distinct,
histogram, num_buckets,
to_char(LAST_ANALYZED, 'yyyy-dd-mm hh24:mi:ss') LAST_ANALYZED
from dba_tab_col_statistics
where table_name='EMP';
--查看表的各个列的统计信息收集情况。

alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';

select t.TABLE_NAME,t.NUM_ROWS,t.BLOCKS,t.LAST_ANALYZED from user_tables t where table_name in ('T1','T2');
select t.TABLE_NAME,t.NUM_ROWS,t.BLOCKS,t.LAST_ANALYZED from user_tables t where table_name='dba_objects';

BEGIN
  DBMS_STATS.SET_TABLE_PREFS ( ownname =>'XXX', tabname =>'T1', pname =>'STALE_PERCENT', pvalue =>'5');
END;
/


BEGIN
  DBMS_SCHEDULER.DISABLE('GATHER_STATS_JOB');
END;
/

DBMS_STATS.LOCK_TABLE_STATS(
ownname    VARCHAR2,
tabname    VARCHAR2
);
 

猜你喜欢

转载自blog.csdn.net/lin5450lin/article/details/89029008