注册
DM通过系统包并行收集统计信息
培训园地/ 文章详情 /

DM通过系统包并行收集统计信息

山水清音 2023/09/26 1111 0 0

    实际工作中有些项目遇到一些表数据较大,收集统计信息是件棘手的事,因为经常在业务不忙时运行 DBMS_STATS.GATHER_SCHEMA_STATS('用户名',100,TRUE,'FOR ALL COLUMNS SIZE AUTO') 收集一个模式的统计信息时,耗时很久甚至需要好几天时间。
    另外,以上SQL只能使用一个CPU,在夜晚进行统计时数据库一般处于较闲的状态,不能合理使用CPU资源。所以可以采用多会话的方式来收集。
    登录SYSDBA用户,先创建系统包,

SP_CREATE_SYSTEM_PACKAGES(1); 

    再创建统计信息记录表如下:

CREATE TABLE DB_TAB_STATS(TABLE_NAME VARCHAR2(100),STAT_FLAG VARCHAR2(5));

    初始化统计信息记录表,如目标是用户DMHR下的所有表

INSERT INTO DB_TAB_STATS(TABLE_NAME) SELECT TABLE_NAME FROM DBA_TABLES WHERE OWNER = DMTEST;
UPDATE DB_TAB_STATS SET STAT_FLAG = 0;
COMMIT;
--收集统计信息
BEGIN
FOR TB IN (SELECT ROWID,TABLE_NAME FROM DB_TAB_STATS WHERE ROWID<=1000) 
LOOP
      DBMS_STATS.GATHER_TABLE_STATS('DMTEST',TB.TABLE_NAME,NULL,100,TRUE,'FOR ALL COLUMNS SIZE AUTO');
        UPDATE DB_TAB_STATS SET STAT_FLAG = 1 WHERE TABLE_NAME = TB.TABLE_NAME;
        COMMIT;
    END LOOP;
END;

    用ROWID可以将用户表分成多个区间进行收集。比如有20000张表需要收集,分成15000、500110000、1000115000和1500120000来收集的话,就能利用到4个CPU,提高收集统计信息的效率。如果发生报错而中断的情况,能根据表中的STAT_FLAG列来检查进度,以便于下次继续收集。
    另一种方式:
DBMS_STATS.GATHER_SCHEMA_STATS(‘模式名’,100,TRUE,‘FOR ALL INDEXED SIZE AUTO’,8);
    这里8为并行度8;详细解释见官方包手册。可以批量拼接出语句切块并行执行。更新统计信息时需测试验证,不管哪种方式,需找到合适的并行度,以免影响现有业务使用。
    如上两种方式仅供参考,以现场环境为主,需测试验证不影响现有业务后在使用。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服