[统计信息系列7] Oracle 11g的自动统计信息收集

(一)统计信息收集概述
在Oracle 11g中,默认有3个自动任务,分别是:自动统计信息收集、SQL调优顾问、段空间调整顾问,查看方法如下:
SQL> SELECT CLIENT_NAME,TASK_NAME,OPERATION_NAME,STATUS FROM dba_autotask_task; CLIENT_NAME TASK_NAME OPERATION_NAME STATUS
-------------------------------- -------------------------- -------------------------- --------
sql tuning advisor AUTO_SQL_TUNING_PROG automatic sql tuning task ENABLED
auto optimizer stats collection gather_stats_prog auto optimizer stats job ENABLED
auto space advisor auto_space_advisor_prog auto space advisor job ENABLED
灰色背景行代表自动统计信息收集,使用的任务为gather_stats_prog。gather_stats_prog调用了DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC存储过程
SQL> SELECT PROGRAM_NAME,PROGRAM_TYPE,PROGRAM_ACTION FROM dba_scheduler_programs WHERE PROGRAM_NAME = 'GATHER_STATS_PROG'; PROGRAM_NAME PROGRAM_TYPE PROGRAM_ACTION
------------------------------ ---------------- --------------------------------------------------------------------------------
GATHER_STATS_PROG STORED_PROCEDURE dbms_stats.gather_database_stats_job_proc
在Oracle 11g中,一共配置了7个自动维护窗口,每天一个窗口
SQL> SELECT WINDOW_NAME,AUTOTASK_STATUS FROM dba_autotask_window_clients ; WINDOW_NAME AUTOTASK_STATUS
------------------------------ ---------------
MONDAY_WINDOW ENABLED
TUESDAY_WINDOW ENABLED
WEDNESDAY_WINDOW ENABLED
THURSDAY_WINDOW ENABLED
FRIDAY_WINDOW ENABLED
SATURDAY_WINDOW ENABLED
SUNDAY_WINDOW ENABLED
每个窗口的运行时间如下:
SQL> SELECT a.WINDOW_NAME,a.REPEAT_INTERVAL,a.duration FROM dba_scheduler_windows a WHERE ENABLED = 'TRUE'; 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
可以看到,从周一到周五,窗口运行时间为晚上22点开始,最多运行4个小时,周六周日从早上6点开始,最多运行20个小时。
在窗口任务启动时,自动任务GATHER_STATS_PROG每次运行时会先生成ORA$AT_OS_OPT_xxx的作业,然后再执行这个作业。
SQL> SELECT a.JOB_NAME,a.ACTUAL_START_DATE,a.RUN_DURATION,a.STATUS
2 FROM dba_scheduler_job_run_details a
3 WHERE a.JOB_NAME LIKE 'ORA$AT_OS_OPT%'; JOB_NAME ACTUAL_START_DATE RUN_DURATION STATUS
--------------------- ---------------------------------- ---------------- ------------
ORA$AT_OS_OPT_SY_1 25-MAY-20 10.00.02.042065 PM PRC +000 00:01:24 SUCCEEDED
ORA$AT_OS_OPT_SY_21 30-MAY-20 09.25.57.005710 AM PRC +000 00:00:37 SUCCEEDED
ORA$AT_OS_OPT_SY_41 30-MAY-20 01.26.30.842460 PM PRC +000 00:00:43 SUCCEEDED
ORA$AT_OS_OPT_SY_61 30-MAY-20 05.26.41.292037 PM PRC +000 00:00:31 SUCCEEDED
总结:Oracle 11g自动统计信息收集是通过每天执行自动任务gather_stats_prog来实现的,它每天会自动生成ORA$AT_OS_OPT_xxx的作业,然后执行作业来收集统计信息,其本质也是执行了DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC存储过程。
(二)统计信息收集策略
每次自动收集统计信息,并不是对所有表都进行收集,Oracle只对那些已经统计信息失效的对象进行收集,那么Oracle如何判断哪些对象的统计信息失效了呢?
在Oracle 11g中,如果参数STATISTICS_LEVEL的值为TYPICAL(默认)或者ALL,则DBA_TAB_MODIFICATIONS会记录自上次自动统计信息收集完成之后对目标表的insert、update、delete的操作影响行数,并且还会记录自从上次自动收集统计信息之后是否发生过truncate。需要注意的是DBA_TAB_MODIFICATIONS并不会实时更新,如果需要查看最新信息,可以手动更新该表的信息:
EXEC dbms_stats.flush_database_monitoring_info();
Oracle收集失效的统计信息的策略:自上次自动统计信息收集作业完成之后,如果DBA_TAB_MODIFICATIONS中记录的INSERT+UPDATE+DELETE所影响的行记录之和超过了DBA_TABLES中目标表记录数的10%,或者是自上次统计信息收集完成之后目标表执行过truncate操作,那么Oracle会认为目标表的统计信息已经失效,自动统计信息收集作业就会对目标表重新收集统计信息。
(三)禁用/启用自动统计信息收集
在某些情况下,需要禁用自动统计信息的收集,可以使用以下3种方法,每种方法禁用范围不同。
(3.1)使用以下方法可以禁用/启用自动统计信息收集
SQL> EXEC dbms_auto_task_admin.disable(client_name=> 'auto optimizer stats collection',operation=> NULL,window_name=> NULL);
确认是否已经关闭:
SELECT WINDOW_NAME,AUTOTASK_STATUS,OPTIMIZER_STATS,SEGMENT_ADVISOR,SQL_TUNE_ADVISOR FROM DBA_AUTOTASK_WINDOW_CLIENTS
如果要启用,可以使用如下方法重新打开自动统计信息收集:
SQL> EXEC dbms_auto_task_admin.enable(client_name=> 'auto optimizer stats collection',operation=> NULL,window_name=> NULL);
再次查询,确认已经开启:

(3.2)使用DBMS_SCHEDULER.DISABLE可以禁用维护窗口,从而禁用统计信息收集
例子1:禁掉周一的自动维护作业,包括统计信息收集、段顾问、sql调优顾问
EXEC dbms_scheduler.disable(NAME=> 'SYS.MONDAY_WINDOW',FORCE=> TRUE)
结果如下:
SELECT a.WINDOW_NAME,a.enabled FROM dba_scheduler_windows a where a.window_name = 'MONDAY_WINDOW';
启用周一的自动维护作业,包括统计信息收集、段顾问、sql调优顾问
EXEC dbms_scheduler.enable(NAME=>'SYS.MONDAY_WINDOW');
(3.3)使用DBMS_SCHEDULER.DISABLE可以禁用维护窗口中的统计信息收集
例子2:禁掉周二的自动统计信息收集,段顾问、sql调优顾问保持开启
EXEC dbms_auto_task_admin.disable(client_name=>'auto optimizer stats collection',operation=>NULL,window_name=>'TUESDAY_WINDOW');
查询结果如下:
SELECT WINDOW_NAME,AUTOTASK_STATUS,OPTIMIZER_STATS,SEGMENT_ADVISOR,SQL_TUNE_ADVISOR FROM DBA_AUTOTASK_WINDOW_CLIENTS ;
再次开启:
EXEC dbms_auto_task_admin.enable(client_name=>'auto optimizer stats collection',operation=>NULL,window_name=>'TUESDAY_WINDOW');
(四)调整自动统计信息收集
默认的统计信息如下,从周一到周五,窗口运行时间为晚上22点开始,最多运行4个小时,周六周日从早上6点开始,最多运行20个小时。

我们可以对其进行修改,修改的方法如下:
1.先禁用窗口:DBMS_SCHEDULER.DISABLE()
2.修改窗口的属性:DBMS_SCHEDULER.SET_ATTRIBUTE()
3.启用窗口:DBMS_SCHEDULER.ENABLE()
例子1:将周二的起始执行时间调整到23点
-- 1.禁用窗口
EXEC dbms_scheduler.disable(NAME=> 'SYS.MONDAY_WINDOW',FORCE=> TRUE) -- 2.修改启动时间为23点
EXEC dbms_scheduler.set_attribute(name => 'SYS.MONDAY_WINDOW',attribute => 'REPEAT_INTERVAL',value => 'freq=daily;byday=TUE;byhour=23;byminute=0; bysecond=0'); -- 3.启用窗口
EXEC dbms_scheduler.enable(NAME=>'SYS.MONDAY_WINDOW');
查看结果:

(五)列的直方图统计信息收集方式修改
在Oracle 11g中,Oracle默认直方图的统计信息收集方式是AUTO,即Oracle会根据负载以及列的使用情况来确定对哪些列收集直方图信息,为了更好地利用直方图统计信息的同时保持执行计划的稳定,推荐对直方图统计信息的收集策略是对已经存在直方图的列才收集直方图统计信息,即以REPEAT方式收集。
查看默认的直方图收集策略:
SQL> SELECT dbms_stats.get_prefs('METHOD_OPT') FROM dual;
DBMS_STATS.GET_PREFS('METHOD_O
--------------------------------------------------------------------------------
FOR ALL COLUMNS SIZE AUTO
修改直方图策略:
SQL> EXEC dbms_stats.set_global_prefs(pname => 'METHOD_OPT',pvalue => 'FOR ALL COLUMNS SIZE REPEAT');
PL/SQL procedure successfully completed
查看修改后的默认的直方图收集策略:
SQL> SELECT dbms_stats.get_prefs('METHOD_OPT') FROM dual;
DBMS_STATS.GET_PREFS('METHOD_O
--------------------------------------------------------------------------------
FOR ALL COLUMNS SIZE REPEAT
(六)统计信息阈值修改
在Oracle 11g中,默认统计信息的收集阈值为10%,即10%的行数据发生变化或者执行了truncate,才会再次收集统计信息。我们可以使用下面的方法针对单个表修改阈值。
例子1:修改test01表的统计信息收集阈值为5%。
查看初始的阈值:
SQL> SELECT dbms_stats.get_prefs(pname => 'STALE_PERCENT',ownname => 'LIJIAMAN',tabname => 'TEST01') FROM dual; DBMS_STATS.GET_PREFS(PNAME=>'S
--------------------------------------------------------------------------------
10
修改阈值为5:
SQL> EXEC dbms_stats.set_table_prefs(ownname => 'LIJIAMAN',tabname => 'TEST01',pname => 'STALE_PERCENT',pvalue => 5);
PL/SQL procedure successfully completed
确认修改后的阈值:
SQL> SELECT dbms_stats.get_prefs(pname => 'STALE_PERCENT',ownname => 'LIJIAMAN',tabname => 'TEST01') FROM dual; DBMS_STATS.GET_PREFS(PNAME=>'S
--------------------------------------------------------------------------------
5
需要注意的是:当阈值为0时,不管数据如何变化,每天都会自动收集统计信息。
【完】
[统计信息系列7] Oracle 11g的自动统计信息收集的更多相关文章
- Oracle 11g RAC 自动应用PSU补丁简明版
环境:Oracle RAC(GI 11.2.0.4 + DB 11.2.0.4) 本文应用补丁信息: Patch 23615403 - Combo of OJVM Component 11.2.0.4 ...
- Oracle 11g 之自动收集统计信息
在Oracle的11g版本中提供了统计数据自动收集的功能.在部署安装11g Oracle软件过程中,其中有一个步骤便是提示是否启动这个功能(默认是启用这个功能). 1.查看自动收集统计信息的任务及状态 ...
- Oracle 11g 的 自动内存管理
oracle11g 设置memory_target的值,开启AMM(Auto Memory Management),剩下的Oracle就可以自动维护了 参考:1.https://www.cnblogs ...
- Oracle 11g 数据库自动备份执行脚本
@echo offsetlocal enabledelayedexpansiontitle %date% %time:~,8% by LiaoNing Sunray Software Technolo ...
- oracle 11g中的自动维护任务管理
因为人员紧缺,最近又忙着去搞性能优化的事情,有时候真的是不想再搞这个事情,只是没办法,我当前的绩效几乎取决于这个项目的最终成绩,所以不管是人的事还是事的事,都得去让他顺利推进. 前段时间发生还有几台服 ...
- oracle 11g 分区表创建(自动按年、月、日分区)
前言:工作中有一张表一年会增长100多万的数据,量虽然不大,可是表字段多,所以一年下来也会达到 1G,而且只增不改,故考虑使用分区表来提高查询性能,提高维护性. oracle 11g 支持自动分区,不 ...
- Oracle 11g 单实例静默安装实战记录(linux)
oracle 11g 单实例静默安装 AUTHOR:Oracle_Ran 环境规划: OS Version : Red Hat Enterprise Linux Server release 6.7 ...
- Oracle的自动统计信息不收集直方图的信息
Oracle的自动统计信息不收集直方图的信息 在oracle9i中,默认的统计信息收集是不收集直方图信息的,也就是说默认的MOTHOD_OPT模式为FOR ALL COLUMNS SIZE 1 在10 ...
- Oracle自动统计信息的收集原理及实验
[日期:2014-11-21]来源:Linux社区 作者:stevendbaguo[字体:大 中 小] 从Oracle Database 10g开始,Oracle在建库后就默认创建了一个名为GATH ...
随机推荐
- HTTPS简单介绍
在HTTP协议中有可能存在信息窃听或者身份伪装等问题,使用HTTPS协议通信机制可以有效地防止这些问题. 1 HTTP协议的缺点 通信使用明文,内容可能被窃听 不用验证通信方的身份,因此可能会遭遇伪装 ...
- 【HBase】带你了解一哈HBase的各种预分区
目录 简单了解 概述 设置预分区 一.手动指定预分区 二.使用16进制算法生成预分区 三.将分区规则写在文本文件中 四.使用JavaAPI进行预分区 简单了解 概述 由上图可以看出,每一个表都有属于自 ...
- SwiftUI - 一起来仿写微信APP之一首页列表视图
简介 最近在学习 SwiftUI ,我一般都是先去学习界面布局,所以就想着仿写一下经常使用的软件的界面,所以先拿微信开刀.因为不想一次性发太多的内容,所以只好将主题分解,一部分一部分地去讲,接下来我们 ...
- gets() 、 getchar() 、 getch() 、getche()、gets()、 scanf()的区别
1.getchar().getche().getch() (1).getchar 函数用于从标准输入设备键盘读入单个字符,返回表示读入字符的ASCII码值,并在屏上显示该字符:头文件是 stdio.h ...
- 弹弹弹 打造万能弹性layout
demo地址:https://github.com/cmlbeliever/BounceLayout 最近任务比较少,闲来时间就来研究了android事件传播机制.根据总结分析的结果,打造出万能弹性l ...
- android 百度地图v3.2.0获取实际地址
百度地图升级到v3.2.0后,api发生挺大的变化的,但是下载的Demo却不是最新版本的. 在v3.2.0之前获取详细地址只要:option.setIsNeedAddress(true); 但是升级后 ...
- POI 导入excel数据自动封装成model对象--介绍
1.项目开发中,导入输入应该是常用的基本功能.我们经常会使用excel将数据导入到数据库,在导入之前必须得将excel数据转换成javaBean对象 2.由于此功能经常使用,所以开发此工具类方便日后轻 ...
- 一文解读C# 动态拦截第三方进程中的方法函数(外挂必备)
一.前言 由于项目需要,最近研究了一下跨进程通讯改写第三方程序中的方法(运行中),把自己程序中的目标方法直接覆盖第三方程序中的方法函数:一直没有头绪,通过搜索引擎找了一大堆解决方案,资料甚是稀少,最后 ...
- 树莓派ssh总掉线
之前入手了一个树莓派,但是远程ssh连接经常掉线,开始以为是电源不行,导致机器重启,后面加了一个显示器,观察了一段时间,发现机器并没有重启,应该是WiFi掉线了,在网上发现,树莓派如果一段网络没有流量 ...
- 3.11 Go Struct结构体
3.11 Go Struct结构体 Golang支持OOP面向对象编程. Go的结构体struct如同python的class. Go基于struct实现OOP特性,只有组合composition这个 ...