在达梦数据库运维中,统计信息的准确性直接影响SQL执行计划的优劣。对于大表,我们通常采用只统计索引列,分区列或者采样率策略以平衡性能与准确性;但对于小表,建议采用100%全量收集,以确保统计信息精准无误。
然而,在实际生产环境中,往往存在大量小表,人工逐一收集效率低下。本文分享一个自动化收集行数≤50万的小表统计信息的存储过程及定时任务配置方案。
步骤1:创建存储过程
CREATE OR REPLACE PROCEDURE PROC_GATHER_SMALL_TABLE_STATS
AS
v_threshold BIGINT := 500000; -- 只收集行数 <= 50万 的表
v_sql VARCHAR(1000);
BEGIN
-- 遍历所有模式
FOR sch IN (SELECT name FROM sys.sysobjects WHERE type$ = 'SCH') LOOP
-- 过滤系统模式,避免收集系统表
IF sch.name NOT IN ('SYS','SYSTEM','SYSAUDITOR','SYSJOB','SYSSSO','CTISYS','DMHS','GLOBAL') THEN
-- 会话级设置哈希桶数(仅当前会话生效)
v_sql := 'sf_set_SESSION_para_value(''HAGR_HASH_SIZE'', 500000)';
EXECUTE IMMEDIATE v_sql;
-- 遍历当前模式下的所有表
FOR tbl IN (SELECT table_name FROM dba_tables WHERE owner = sch.name) LOOP
-- 仅当表行数 <= 阈值时才收集统计信息
IF table_rowcount(sch.name, tbl.table_name) <= v_threshold THEN
EXECUTE IMMEDIATE 'DBMS_STATS.GATHER_TABLE_STATS(''' || sch.name || ''', ''' || tbl.table_name || ''', NULL, 100, TRUE, ''FOR ALL COLUMNS SIZE AUTO'')';
END IF;
END LOOP;
END IF;
END LOOP;
END;
/
步骤2:配置定时任务(每日凌晨1点执行)
-- 创建作业
CALL SP_CREATE_JOB('statistics', 1, 0, '', 0, 0, '', 0, '');
-- 开始作业配置
CALL SP_JOB_CONFIG_START('statistics');
-- 添加作业步骤(调用存储过程)
CALL SP_ADD_JOB_STEP('statistics', 'statistics1', 0, 'PROC_GATHER_SMALL_TABLE_STATS;', 0, 0, 0, 0, NULL, 0);
-- 添加调度计划:每周六01:00执行
CALL SP_ADD_JOB_SCHEDULE('statistics', 'statistics1', 1, 2, 1, 64, 0, '01:00:00', NULL, '2021-06-09 22:54:37', NULL, '');
-- 提交作业配置
CALL SP_JOB_CONFIG_COMMIT('statistics')
https://eco.dameng.com
文章
阅读量
获赞
