oracle dbms_stat与analyze 获取有效的统计信息(4)

#  设置dbms_stats
10g:可修改cascade,estimate_percent,degree,method_opt,no_invalidate,granularity 用set_param修改这些可以(需要analyze any dictionary&analyze any权限)
get_param获取 当前值


SQL> select dbms_stats.get_param('CASCADE') from dual;

DBMS_STATS.GET_PARAM('CASCADE')
--------------------------------------------------------------------------------
DBMS_STATS.AUTO_CASCADE

#直接获取这些参数的值
SELECT sname AS parameter, nvl(spare4,sval1) AS default_value
FROM sys.optstat_hist_control$
WHERE sname IN ('CASCADE','ESTIMATE_PERCENT','DEGREE',
'METHOD_OPT','NO_INVALIDATE','GRANULARITY');

11g:对dbms_stats的配置有了改进,default=首选项(preference),另外可在schema,表级设置(10g是在global 设置),如果使用get_param(set/reset_param_default)都将废弃(需要analyze any dictionary&analyze any权限)

11g可以修改cascade,estimate_percent,degree,method_opt,no_invalidate,granularity,publish,increment,statle_percent的default值
1.set_global_prefs(代替set_param,自己建立的和数据字典都行)
2.set_database_prefs(仅仅用于自己建的object,数据字典不行)
3.set_schema_prefs(schema的首选项)
4.set_table_prefs(表级)


#在使用set_database_prefs&set_schema_prefs时候其中的所有对象都转成表级别的(既 他们只是调用set_table_prefs 对其中的object设,但这也表示新建立的object会采用global选项)
#表级最高 有表级使用表级,没有才用global级别
#查询global级别设置
SELECT sname AS parameter, nvl(spare4,sval1) AS default_value
FROM sys.optstat_hist_control$
WHERE sname IN ('CASCADE','ESTIMATE_PERCENT','DEGREE',
'METHOD_OPT','NO_INVALIDATE','GRANULARITY');
#查询表级dba_tab_stat_prefs
SELECT table_name, preference_name, preference_value
 FROM dba_tab_stat_prefs
 WHERE lower(owner) = '&owner'
 AND lower(table_name)='&tablename'
ORDER BY table_name, preference_name;

#获取是get,恢复是reset,删除是delete

 


*****************10g 自动收集对象统计信息job
oracle 逐渐让query optimizer认识到统计信息的正确性,所以一直在优化收集统计信息方面的工作
10g 是由scheduler来完成的(下面脚本来自trouble shooting oracle),job_name就是GATHER_STATS_JOB


SQL> COLUMN program_owner FORMAT A13
SQL> COLUMN program_name FORMAT A17
SQL> COLUMN schedule_owner FORMAT A14
SQL> COLUMN schedule_name FORMAT A24
SQL> COLUMN schedule_type FORMAT A15
SQL> COLUMN enabled FORMAT A7
SQL> COLUMN state FORMAT A9
SQL> COLUMN program_type FORMAT A16
SQL> COLUMN program_action FORMAT A41
SQL> COLUMN enabled FORMAT A7
SQL> COLUMN window_name FORMAT A16
SQL> COLUMN repeat_interval FORMAT A37
SQL> COLUMN duration FORMAT A13
SQL> COLUMN enabled FORMAT A7
SQL>
SQL>
SQL> SELECT program_name, schedule_name, schedule_type, enabled, state
  2  FROM dba_scheduler_jobs
  3  WHERE wner = 'SYS'
  4  AND job_name = 'GATHER_STATS_JOB';


PROGRAM_NAME      SCHEDULE_NAME            SCHEDULE_TYPE   ENABLED STATE
----------------- ------------------------ --------------- ------- ---------
GATHER_STATS_PROG MAINTENANCE_WINDOW_GROUP WINDOW_GROUP    TRUE    SCHEDULED

可以看到这个scheduler中信息 是一个窗口组,里面还有一个过程GATHER_STATS_PROG
SQL> SQL>
SQL> SELECT program_action, number_of_arguments, enabled
  2  FROM dba_scheduler_programs
  3  WHERE wner = 'SYS'
  4  AND program_name = 'GATHER_STATS_PROG';


PROGRAM_ACTION                            NUMBER_OF_ARGUMENTS ENABLED
----------------------------------------- ------------------- -------
dbms_stats.gather_database_stats_job_proc                   0 TRUE

看这里面调用的程序执行的动作(调用dbms_stats.gather_database_stats_job_proc 未带参数)


SQL> SQL> SELECT w.window_name, w.repeat_interval, w.duration, w.enabled
  2  FROM dba_scheduler_jobs j, dba_scheduler_wingroup_members m,
  3       dba_scheduler_windows w
  4  WHERE j.schedule_name = m.window_group_name
  5  AND m.window_name = w.window_name
  6  AND j.owner = 'SYS'
  7  AND j.job_name = 'GATHER_STATS_JOB'
  8  AND j.schedule_type = 'WINDOW_GROUP';


WINDOW_NAME      REPEAT_INTERVAL                       DURATION      ENABLED
---------------- ------------------------------------- ------------- -------
WEEKNIGHT_WINDOW freq=daily;byday=MON,TUE,WED,THU,FRI; +000 08:00:00 TRUE
                 byhour=22;byminute=0; bysecond=0

WEEKEND_WINDOW   freq=daily;byday=SAT;byhour=0;byminut +002 00:00:00 TRUE
                 e=0;bysecond=0


SQL> SQL> SELECT w.window_name, w.repeat_interval, w.duration, w.enabled
  2  FROM dba_scheduler_wingroup_members m, dba_scheduler_windows w
  3  WHERE m.window_name = w.window_name
  4  AND m.window_group_name = 'MAINTENANCE_WINDOW_GROUP';


WINDOW_NAME      REPEAT_INTERVAL                       DURATION      ENABLED
---------------- ------------------------------------- ------------- -------
WEEKNIGHT_WINDOW freq=daily;byday=MON,TUE,WED,THU,FRI; +000 08:00:00 TRUE
                 byhour=22;byminute=0; bysecond=0

WEEKEND_WINDOW   freq=daily;byday=SAT;byhour=0;byminut +002 00:00:00 TRUE
                 e=0;bysecond=0


# MAINTENANCE_WINDOW_GROUP-调用过程GATHER_STATS_PROG-调用dbms_stats.gather_database_stats_job_proc
# MAINTENANCE_WINDOW_GROU包含2个member,一个是夜间一个是周末,夜间22点开始运行8小时,周末全天
#默认会在负载低的时候执行,如果负载一直很好,也会无法完成
#dbms_schedluer.enable(name=>'sys.gather_stats_job'),dbms_schedluer.enable(name=>'sys.gather_stats_job') 开关(default sys可执行其他user要有改对象的alert权限,既alert on gater_stats_jobs)

#检查自动收集执行情况
set linesize 1000
col job_name format a20
 SELECT log_id, job_name, status,
           TO_CHAR (log_date, 'YYYY-MM-DD HH24:MI:SS') log_date
      FROM dba_scheduler_job_run_details
    WHERE job_name = 'GATHER_STATS_JOB' order by log_date desc;

 

#修改自动收集内容
#execute dbms_output.put_line(dbms_stats.get_param(pname=>'autostats_target'))
SQL> set serveroutput on

SQL> execute dbms_output.put_line(dbms_stats.get_param(pname=>'autostats_target'))
AUTO

PL/SQL procedure successfully completed. 可以看到 值是auto

It takes the following values:
 'ALL'    -- statistics collected for all objects in system
 'ORACLE' -- statistics collected for all oracle owned objects
 'AUTO'   -- oracle decides for which objects to collect stats


In Oracle10g and Oracle11g Release 1 'ALL' and 'AUTO' are equivalent(可以看到 10g-11g r1中all=auto) 而auto是默认的

 

#可以看到实际上oracle 限制下列列表中schema自动收集
'ORACLE' actually restricts the list of schemas for which the automatic stats
gathering job will gather statistics to a list of Oracle component system
schemas generated by the following queries:

In 10.1:

select distinct u.name
from registry$ r, user$ u
where r.schema#=u.user#
and   r.status in (1,3,5)
and   r.namespace = 'SERVER';

In 10.2 and 11.1:

select  distinct name from (
  select u.name
    from registry$ r, user$ u
    where r.status in (1,3,5)
    and   r.namespace = 'SERVER'
    and   r.schema#=u.user#
  union all
  select u.name -- get additional component schemas
    from registry$ r, registry$schemas s, user$ u
    where r.status in (1,3,5)
    and   r.namespace = 'SERVER'
    and   r.cid=s.cid
    and   s.schema#=u.user#)
order by name;

e.g. such schemas are SYS, SYSMAN, WMSYS and EXFSYS in a sample database.

 

 

 

 

11g(以下查询脚本来自oracle trouble shooting)

#收集信息集成了自动维护任务
SQL> COLUMN task_name FORMAT A17
SQL> COLUMN status FORMAT A7
SQL> COLUMN program_action FORMAT A41
SQL> COLUMN enabled FORMAT A7
SQL> COLUMN window_group FORMAT A14
SQL> COLUMN window_name FORMAT A16
SQL> COLUMN repeat_interval FORMAT A42
SQL> COLUMN duration FORMAT A13
SQL> COLUMN enabled FORMAT A7
SQL> SELECT task_name, status
  2  FROM dba_autotask_task
  3  WHERE client_name = 'auto optimizer stats collection';

TASK_NAME         STATUS
----------------- -------
gather_stats_prog ENABLED             ~~~获得的其实就是program_name                      

SQL> SELECT program_action, number_of_arguments, enabled
  2  FROM dba_scheduler_programs
  3  WHERE wner = 'SYS'
  4  AND program_name = 'GATHER_STATS_PROG';

PROGRAM_ACTION                            NUMBER_OF_ARGUMENTS ENABLED
----------------------------------------- ------------------- -------
dbms_stats.gather_database_stats_job_proc                   0 TRUE

看到这个program里的调用就是不带任何参数执行dbms_stats.gather_database_stats_job_proc

SQL> SELECT window_group
  2  FROM dba_autotask_client
  3  WHERE client_name = 'auto optimizer stats collection';

WINDOW_GROUP
--------------
ORA$AT_WGRP_OS~~~~~~~~所属的window

SQL> 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
-------
MONDAY_WINDOW    freq=daily;byday=MON;byhour=22;byminute=0; +000 04:00:00
                  bysecond=0
TRUE

TUESDAY_WINDOW   freq=daily;byday=TUE;byhour=22;byminute=0; +000 04:00:00
                  bysecond=0
TRUE

WEDNESDAY_WINDOW freq=daily;byday=WED;byhour=22;byminute=0; +000 04:00:00

WINDOW_NAME      REPEAT_INTERVAL                            DURATION
---------------- ------------------------------------------ -------------
ENABLED
-------
                  bysecond=0
TRUE

THURSDAY_WINDOW  freq=daily;byday=THU;byhour=22;byminute=0; +000 04:00:00
                  bysecond=0
TRUE

FRIDAY_WINDOW    freq=daily;byday=FRI;byhour=22;byminute=0; +000 04:00:00
                  bysecond=0

WINDOW_NAME      REPEAT_INTERVAL                            DURATION
---------------- ------------------------------------------ -------------
ENABLED
-------
TRUE

SATURDAY_WINDOW  freq=daily;byday=SAT;byhour=6;byminute=0;  +000 20:00:00
                 bysecond=0
TRUE

SUNDAY_WINDOW    freq=daily;byday=SUN;byhour=6;byminute=0;  +000 20:00:00
                 bysecond=0
TRUE

WINDOW_NAME      REPEAT_INTERVAL                            DURATION
---------------- ------------------------------------------ -------------
ENABLED
-------


7 rows selected.

#可以看到11g时间调整了,做了7个窗口,其中1-5每天晚上22点开始执行4小时
周末6点开始执行20小时

 

#11g开启/关闭 自动收集统计信息
dbms_auto_task_admin.enable(client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL)
dbms_auto_task_admin.disable(client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL)

 

#lock统计信息

SQL> create table t1(a int);

Table created.

SQL> insert into t1 values(1);

1 row created.

SQL> commit;

Commit complete.

SQL> execute dbms_stats.gather_table_stats('SYS','T1');

PL/SQL procedure successfully completed.

SQL> select num_rows from user_tables where table_name='T1';

  NUM_ROWS
----------
         1

 

#lock该schema下所有patch
execute dbms_stats.lock_schema_stats(ownname=>'&user');
#lock一张表的统计信息
execute dbms_stats.lock_table_stats(ownname=>'&user',tabname=>'&tablename');


SQL> insert into t1 values(2);

1 row created.

SQL> commit;

Commit complete.

SQL> execute dbms_stats.lock_table_stats(ownname=>'&user',tabname=>'&tablename');
Enter value for user: SYS
Enter value for tablename: T1

PL/SQL procedure successfully completed.


SQL> select num_rows,table_lock from user_tables where table_name='T1';

  NUM_ROWS TABLE_LO
---------- --------
         1 ENABLED

SQL>
SQL> execute dbms_stats.gather_table_stats('SYS','T1');

BEGIN dbms_stats.gather_table_stats('SYS','T1'); END;

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


#force可以强制收集
SQL> SQL> execute dbms_stats.gather_table_stats('SYS','T1',force=>TRUE);


PL/SQL procedure successfully completed.

SQL> SQL> select num_rows,table_lock from user_tables where table_name='T1';

  NUM_ROWS TABLE_LO
---------- --------
         2 enabled

#unlock
SQL> execute dbms_stats.unlock_table_stats(ownname=>'&user',tabname=>'&tablename');
Enter value for user: SYS
Enter value for tablename: T1

#查询哪些表的统计信息被lock了
select table_name from user_tab_statistics where stattype_locked is not null;

 

SQL> create index t1_id on t1(a);

Index created.

SQL> select table_name from user_tab_statistics where stattype_locked is not null;

TABLE_NAME
------------------------------

T1


SQL> alter index t1_id rebuild;

Index altered.

SQL> alter index t1_id rebuild compute statistics; 显示指定报错
alter index t1_id rebuild compute statistics
*
ERROR at line 1:
ORA-38029: object statistics are locked

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12020513/viewspace-664241/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12020513/viewspace-664241/

你可能感兴趣的:(数据库)