Oracle DBMS_STATS.GATHER_DATABASE_STATS 默认行为
DBMS_STATS.GATHER_DATABASE_STATS
的默认选项究竟是’GATHER’还是’GATHER AUTO’?这个问题非常重要,因为理解默认行为直接影响统计信息收集策略。
一 官方文档确认
根据Oracle 19c官方文档:
- options参数默认值是’GATHER’,不是’GATHER AUTO’
DBMS_STATS.GATHER_DATABASE_STATS (
estimate_percent NUMBER DEFAULT to_estimate_percent_type
(get_param('ESTIMATE_PERCENT')),
block_sample BOOLEAN DEFAULT FALSE,
method_opt VARCHAR2 DEFAULT get_param('METHOD_OPT'),
degree NUMBER DEFAULT to_degree_type(get_param('DEGREE')),
granularity VARCHAR2 DEFAULT GET_PARAM('GRANULARITY'),
cascade BOOLEAN DEFAULT to_cascade_type(get_param('CASCADE')),
stattab VARCHAR2 DEFAULT NULL,
statid VARCHAR2 DEFAULT NULL,
options VARCHAR2 DEFAULT 'GATHER',
objlist OUT ObjectTab,
statown VARCHAR2 DEFAULT NULL,
gather_sys BOOLEAN DEFAULT TRUE,
no_invalidate BOOLEAN DEFAULT to_no_invalidate_type (
get_param('NO_INVALIDATE')),
obj_filter_list ObjectTab DEFAULT NULL);
DBMS_STATS.GATHER_DATABASE_STATS (
estimate_percent NUMBER DEFAULT to_estimate_percent_type
(get_param('ESTIMATE_PERCENT')),
block_sample BOOLEAN DEFAULT FALSE,
method_opt VARCHAR2 DEFAULT get_param('METHOD_OPT'),
degree NUMBER DEFAULT to_degree_type(get_param('DEGREE')),
granularity VARCHAR2 DEFAULT GET_PARAM('GRANULARITY'),
cascade BOOLEAN DEFAULT to_cascade_type(get_param('CASCADE')),
stattab VARCHAR2 DEFAULT NULL,
statid VARCHAR2 DEFAULT NULL,
options VARCHAR2 DEFAULT 'GATHER',
statown VARCHAR2 DEFAULT NULL,
gather_sys BOOLEAN DEFAULT TRUE,
no_invalidate BOOLEAN DEFAULT to_no_invalidate_type (
get_param('NO_INVALIDATE')),
obj_filter_list ObjectTab DEFAULT NULL);
二 默认GATHER行为的完整解释
1. 实际默认行为
-- 完全等价的两种写法
DBMS_STATS.GATHER_DATABASE_STATS;
DBMS_STATS.GATHER_DATABASE_STATS(options => 'GATHER');
2. GATHER模式的特点
- 全量收集:会收集数据库中所有对象的统计信息
- 不考虑数据变化量:不检查STALE_STATS状态
- 完全刷新:确保所有统计信息都是最新的
3. 与GATHER AUTO的核心区别
特性 | GATHER(默认) | GATHER AUTO |
---|---|---|
收集范围 | 所有对象 | 仅需要更新的对象 |
系统影响 | 高 | 低 |
执行时间 | 长 | 短 |
统计信息时效性 | 全部最新 | 可能存在延迟 |
适用场景 | 初始环境/重大变更后 | 日常维护 |
三、生产环境推荐用法
1. 常规维护建议使用GATHER AUTO
-- 显式指定GATHER AUTO是更好的实践
BEGIN
DBMS_STATS.GATHER_DATABASE_STATS(
options => 'GATHER AUTO',
gather_sys => FALSE,
degree => DBMS_STATS.AUTO_DEGREE);
END;
/
2. 需要完全刷新时使用默认GATHER
-- 数据仓库全量加载后等场景
BEGIN
DBMS_STATS.GATHER_DATABASE_STATS(
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
degree => 8); -- 根据系统资源指定并行度
END;
/
四、如何验证当前行为
1. 检查实际收集情况
-- 收集前记录时间戳
ALTER SESSION SET nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
SELECT sysdate FROM dual;
-- 执行收集(使用默认参数)
EXEC DBMS_STATS.GATHER_DATABASE_STATS;
-- 检查哪些表被更新
SELECT owner, table_name, last_analyzed
FROM dba_tables
WHERE last_analyzed > TO_DATE('2023-08-01 10:00:00', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY last_analyzed DESC;
2. 查看默认参数设置
-- 检查options默认值
SELECT dbms_stats.get_prefs('OPTIONS') FROM dual;
-- 检查全局偏好设置
SELECT * FROM sys.optstat_hist_control$;
五、历史版本差异说明
虽然当前文档明确默认是GATHER,但需要注意:
-
Oracle 10g/11g时期:
- 存在一些版本/补丁的默认行为可能不同
- 某些文档曾提到过更智能的默认行为
-
Oracle 12c及以后:
- 明确规范了默认就是GATHER
- 但自动维护任务(自动统计信息收集)使用的是GATHER AUTO逻辑
六、最佳实践总结
-
不要依赖默认值:
- 显式指定options参数
- 确保脚本行为明确可控
-
两种模式的典型场景:
- GATHER AUTO:日常夜间维护作业
- GATHER:月维护窗口/数据迁移后
-
特殊对象处理:
-- 对大表设置单独策略 EXEC DBMS_STATS.SET_TABLE_PREFS('SH', 'SALES', 'ESTIMATE_PERCENT', '5'); -- 对关键业务表提高收集频率 EXEC DBMS_STATS.SET_TABLE_PREFS('HR', 'EMPLOYEES', 'STALE_PERCENT', '1');
-
监控策略:
-- 创建统计信息收集报告 SELECT job_name, status, actual_start_date, run_duration FROM dba_scheduler_job_run_details WHERE job_name LIKE 'GATHER_STATS%' ORDER BY actual_start_date DESC;
DBMS_STATS.GATHER_DATABASE_STATS的默认options参数是’GATHER’,会收集所有对象的统计信息,而不是智能选择。生产环境中显式指定GATHER AUTO通常是更好的选择。
官方文档路径:
https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_STATS.html#GUID-7D7442B5-B060-40E9-AA18-2085E527C3B1