【Oracle专栏】更新多个表的统计信息

Oracle && OceanBase 相关文档,希望互相学习,共同进步

风123456789~-CSDN博客


1.背景

今天执行truncate部分表后,发现user_tables 的num_rows 还是原来的数据,于是进行手动更新。在Oracle中,统计信息对于优化器的决策至关重要。优化器使用统计信息来确定执行查询的最佳路径。

当表中的数据发生大量变化时,优化器可能无法做出最佳决策,因为它依赖的统计信息可能已经过时。统计信息未及时更新 会导致oracle 基于成本的执行计划可能不是最优,查看执行计划是没问题的,但sql实际执行起来确很慢。其中,DBMS_STATS包中的GATHER_TABLE_STATS过程是一种用于收集表、列和索引统计信息的强大工具。通过定期运行DBMS_STATS.GATHER_TABLE_STATS过程,可以确保优化器具有最新的统计信息,从而做出更好的决策。

本文针对oracle数据库的统计信息的手动更新相关内容进行整理、实验。

2. 实验

2.1 实验- 更新指定schema 统计信息

sql 复制代码
--一次性收集某个模式(Schema)下所有表的统计信息,不用逐表操作
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('模式名');

或者

--更精细化统计
BEGIN
  DBMS_STATS.GATHER_SCHEMA_STATS(
    ownname          => '模式名',
    estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,  -- 自动决定采样比例
    method_opt       => 'FOR ALL COLUMNS SIZE AUTO',  -- 自动决定是否建直方图
    degree           => 4,                            -- 并行度,加快速度
    cascade          => TRUE                          -- 同时收集索引统计信息
  );
END;
/

参数说明:

‌ ownname‌:模式名,也就是表的所有者。

‌ estimate_percent‌:采样比例。用 DBMS_STATS.AUTO_SAMPLE_SIZE 让 Oracle 自己决定,通常推荐;也可以手动指定如 100 表示全量分析。

‌ method_opt‌:控制直方图收集方式。'FOR ALL COLUMNS SIZE AUTO' 是常用配置,让 Oracle 根据数据分布自动决定。

‌ degree‌:并行度。表多或大时设置并行(如 4、8)明显加快速度,但要考虑系统负载。

‌cascade‌:设为 TRUE 时,会连同索引统计信息一起收集,建议开启

例子:

sql 复制代码
BEGIN
  DBMS_STATS.GATHER_SCHEMA_STATS('FENG');
END;

2.2 实验 -更新指定表的统计信息

1)知识点

sql 复制代码
DBMS_STATS.GATHER_TABLE_STATS函数的语法如下:

DBMS_STATS.GATHER_TABLE_STATS (
  ownname VARCHAR2,
  tabname VARCHAR2,
  partname VARCHAR2,
  estimate_percent NUMBER,
  block_sample BOOLEAN,
  method_opt VARCHAR2,
  degree NUMBER,
  granularity VARCHAR2,
  cascade BOOLEAN,
  stattab VARCHAR2,
  statid VARCHAR2,
  statown VARCHAR2,
  no_invalidate BOOLEAN
);

ownname:指定表所在的模式名。如果为NULL,则默认为当前模式。

tabname:指定要收集统计信息的表名。

partname:指定要收集统计信息的分区名。如果为NULL,则收集整个表的统计信息。

estimate_percent:指定要收集的样本百分比。

如果为NULL,则默认为100,即收集整个表的统计信息。

block_sample:指定是否使用块采样来收集统计信息。

如果为TRUE,则使用块采样;如果为FALSE,则使用完全采样。默认为FALSE。

method_opt:指定收集统计信息的方法选项。

包括'FOR ALL COLUMNS SIZE AUTO'、'FOR COLUMNS column_list SIZE AUTO'等选项,用于指定要收集统计信息的列和如何收集。

degree:指定并行度,即用于收集统计信息的并行进程数。

如果为NULL,则使用数据库的默认并行度。

granularity:指定收集统计信息的粒度。可设为AUTO'、'ALL'、'COLUMNS'、'INDEXES'等

如,'AUTO'表示自动选择粒度;'ALL'表示收集所有级别的统计信息。

cascade:指定是否级联收集相关对象的统计信息,如索引、触发器等。

如果为TRUE,则级联收集;如果为FALSE,则只收集指定表的统计信息。

stattab:指定存储统计信息的表名。如果为NULL,则使用默认的统计信息表。

statid:指定统计信息的ID。如果为NULL,则Oracle会自动生成一个唯一的ID。

statown:指定存储统计信息的模式名。如果为NULL,则使用当前模式。

no_invalidate:指定是否使现有的统计信息无效。

如果设置为TRUE,则保留现有的统计信息,并在收集新统计信息后将其标记为无效。如果为FALSE或NULL,则在收集新统计信息后删除现有的统计信息。

sql 复制代码
--更新指定表的统计信息
BEGIN
    DBMS_STATS.GATHER_TABLE_STATS(
              ownname => USER,
              tabname => 'SUN_PUBLIC_INFO',
              cascade => TRUE
            );
END;
/

执行截图: 6百万数据,大约执行5分钟

sql 复制代码
或者:
call dbms_stats.gather_table_stats(user,'XPT_BANK_FENG');
call dbms_stats.gather_table_stats('FENG','TEM_TABLE');


SELECT TABLE_NAME, LAST_ANALYZED,a.* 
FROM ALL_TAB_STATISTICS a WHERE A.OWNER = 'FENG';

执行后,查询截图:

2.3 实验 -更新 多个表的统计信息

sql 复制代码
--编写函数,循环更新
create or replace function get_num_rows(p_tname varchar2) RETURN VARCHAR2 IS
    vResult  varchar2(2);
    vFunctionName varchar2(1000);
    vTableName    varchar2(500);
    vMsg          varchar2(1000);
    vCount        number;
    pDataIssue    varchar2(7);
  begin
    vResult       := '0';
    pDataIssue    := to_char(sysdate,'yyyy-mm');
    vTableName    := '' ;   --'OPEN_CNT_ASSCON';

    vFunctionName := 'get_num_rows -更新';
    begin
        GET_LOGGER(pDataIssue, 'get_num_rows', vTableName, '0', '开始跑批');

        FOR t IN (SELECT table_name FROM user_tables t
                  WHERE t.table_name  like 'SUN_PUBLIC_%'or t.table_name like '%RPT%'
                  ) 
        LOOP
            DBMS_STATS.GATHER_TABLE_STATS(
              ownname => USER,
              tabname => t.table_name,
              cascade => TRUE
            );
            GET_LOGGER(pDataIssue, 'get_num_rows', t.table_name, '0', '结束');
       END LOOP;
       GET_LOGGER(pDataIssue, 'get_num_rows', '', '0', '结束跑批');

    EXCEPTION
      WHEN OTHERS THEN
        vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
                substr(SQLERRM, 1, 200);
        GET_LOGGER(pDataIssue, vFunctionName, vTableName, '3', vMsg);
        vResult := '1';
    END;
    return vResult;
end;

查询更新后的统计信息:

sql 复制代码
select T.table_name,T.num_rows from user_tables t
where t.table_name  like 'SUN_PUBLIC_%'
or t.table_name like '%RPT%'
ORDER BY 1

2.4 查看 数据表上次统计更新的时间

sql 复制代码
--查看上次统计信息更新的时间
SELECT TABLE_NAME, LAST_ANALYZED,a.* 
FROM ALL_TAB_STATISTICS a WHERE A.OWNER = 'FENG';

2.5 自动化脚本更新

sql 复制代码
--将如下两个脚本存放到同一目录下,注意修改数据库配置参数,然后使用windows计划任务定期执行动态更新;
--​来源 https://blog.51cto.com/u_14286115/3327958,未验证,应该是可以的。

​
脚本1:自动更新Oracle统计信息.bat
title 自动更新Oracle统计信息[%date%%time%]
sqlplus userName/passWord@192.168.0.1/db_name @gen_sqls.sql | find "call dbms_stats.gather_table_stats">stats_sqls.sql
echo exit>>stats_sqls.sql
sqlplus userName/passWord@192.168.0.1/db_name @stats_sqls.sql
echo 脚本执行完成

 

脚本2:gen_sqls.sql
select
'call dbms_stats.gather_table_stats(''用户名'','''|| TABLE_NAME ||''');' as sqls
from user_tables a
where a.last_analyzed <sysdate-7
and num_rows > 1000
order by num_rows ;
exit;

3.总结

在Oracle数据库CBO基于成本的优化器体系当中,统计信息是优化器生成合理执行计划的核心输入源。统计信息失真、缺失、过期是线上SQL性能抖动、执行计划漂移最主要诱因之一。大量生产故障根因均来自统计信息维护不当:大表批量DML之后统计信息未刷新、直方图丢失、自动收集任务窗口不合理、参考数据表统计信息被自动任务覆盖等。

在Oracle数据库中,DBMS_STATS是一个强大的包,它提供了多种用于收集数据库对象统计信息的函数。其中,DBMS_STATS.GATHER_TABLE_STATS函数是最常用的一种,用于收集表、列和索引的统计信息。这些信息对Oracle的优化器非常重要,它可以帮助优化器制定更有效的查询计划。通过收集统计信息,Oracle可以更好地理解数据的分布和特征,从而更准确地评估查询的成本和效率。

  • 只更新单模式:DBMS_STATS.GATHER_SCHEMA_STATS。
  • 只更新单表:DBMS_STATS.GATHER_TABLE_STATS。
  • 更新整个数据库:DBMS_STATS.GATHER_DATABASE_STATS

应用场景:

  1. 数据库迁移:在将数据库从一个环境迁移到另一个环境时,需要收集源数据库的统计信息,并在目标数据库中重新收集统计信息,以确保优化器能够制定正确的查询计划。

  2. 数据表修改:当数据表的结构或数据发生重大变化时(如添加新列、删除列、大量数据插入或删除等),需重新收集统计信息,确保优化器能够准确评估查询的成本和效率。

  3. 定期维护:为了保持数据库性能的稳定和高效,需要定期收集统计信息。可以通过设置自动化任务或使用Oracle提供的自动收集统计信息的特性来实现

实验验证:ok


项目管理--相关知识

项目管理-项目绩效域1/2-CSDN博客

项目管理-项目绩效域1/2_八大绩效域和十大管理有什么联系-CSDN博客

项目管理-项目绩效域2/2_绩效域 团不策划-CSDN博客

高项-案例分析万能答案(作业分享)-CSDN博客

项目管理-计算题公式【复习】_项目管理进度计算题公式:乐观-CSDN博客

项目管理-配置管理与变更-CSDN博客

项目管理-项目管理科学基础-CSDN博客

项目管理-高级项目管理-CSDN博客

项目管理-相关知识(组织通用治理、组织通用管理、法律法规与标准规范)-CSDN博客


Oracle其他文档,希望互相学习,共同进步

Oracle-找回误删的表数据(LogMiner 挖掘日志)_oracle日志挖掘恢复数据-CSDN博客

oracle 跟踪文件--审计日志_oracle审计日志-CSDN博客

ORA-12899报错,遇到数据表某字段长度奇怪现象:"Oracle字符型,长度50"但length查却没有50_varchar(50) oracle 超出截断-CSDN博客

EXP-00091: Exporting questionable statistics.解决方案-CSDN博客

Oracle 更换监听端口-CSDN博客

相关推荐
杨云龙UP6 小时前
Oracle 19c 单机到单机 Active Data Guard 搭建与巡检操作手册
数据库·oracle·adg·操作指南·data guard·dg搭建
我科绝伦(Huanhuan Zhou)9 小时前
oracle坏块导致备份不了
数据库·oracle·ffmpeg
杨云龙UP10 小时前
Oracle 19c RAC到RAC Active Data Guard标准搭建与巡检指南
运维·服务器·数据库·oracle·adg·data guard·rac到rac
许彰午10 小时前
06-Oracle卸载与重装完整流程
数据库·oracle
我的xiaodoujiao10 小时前
Django 基础知识详细图文教程 13-Django 模型定义与使用 3
数据库·后端·python·测试工具·oracle·django
我科绝伦(Huanhuan Zhou)11 小时前
oracle RAC共享存储换盘操作指南
数据库·oracle
wangbing112511 小时前
重建oracle服务
数据库·oracle
shaibdoio11 小时前
瞬维AI落地经验:AI Agent工具调用准确率怎么提
数据库·人工智能·oracle
jnrjian1 天前
Oracle Inlist 和exists的最佳执行计划
oracle
许彰午2 天前
01-Oracle数据库简介与版本选择
数据库·oracle