# 设置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/