日常运维中,表上常常堆了很多二级索引。有的索引创建后业务几乎不怎么用,却一直占用空间,并增加 DML 维护成本。达梦数据库提供了索引使用监控功能,可通过 V$OBJECT_USAGE 判断索引在监控期间是否被使用过,从而辅助清理无用索引。
说明:索引监控仅支持用户创建的二级索引,不支持聚集索引、系统索引、虚索引、数组索引。
DROP TABLE T_IDX_MON PURGE;
CREATE TABLE T_IDX_MON (
ID INT,
C_CODE VARCHAR(32),
C_NAME VARCHAR(64),
C_NOTE VARCHAR(200)
);
INSERT INTO T_IDX_MON
SELECT LEVEL, 'C'||LEVEL, 'N'||LEVEL, 'NOTE'||LEVEL
FROM DUAL CONNECT BY LEVEL <= 20000;
COMMIT;
-- 创建两个二级索引:一个后续会用到,一个刻意不用
CREATE INDEX IDX_T_CODE ON T_IDX_MON(C_CODE);
CREATE INDEX IDX_T_NOTE ON T_IDX_MON(C_NOTE);
-- 收集统计信息
CALL SP_TAB_STAT_INIT(USER, 'T_IDX_MON');
SELECT INDEX_NAME, TABLE_NAME
FROM USER_INDEXES
WHERE TABLE_NAME = 'T_IDX_MON';
参数 MONITOR_INDEX_FLAG 控制监控方式:
0:手动监控(默认)1:自动监控SELECT PARA_NAME, PARA_VALUE
FROM V$DM_INI
WHERE PARA_NAME = 'MONITOR_INDEX_FLAG';
手动监控时,才能执行 ALTER INDEX ... MONITORING USAGE。若当前为自动监控,可先改回手动:
ALTER SYSTEM SET 'MONITOR_INDEX_FLAG' = 0 BOTH;
ALTER INDEX IDX_T_CODE MONITORING USAGE;
ALTER INDEX IDX_T_NOTE MONITORING USAGE;
SELECT * FROM V$OBJECT_USAGE;
刚开启时,USED 一般为 NO,表示监控开始后尚未被使用。
执行会命中 C_CODE 条件的 SQL,并查看执行计划:
EXPLAIN SELECT * FROM T_IDX_MON WHERE C_CODE = 'C100';
SELECT * FROM T_IDX_MON WHERE C_CODE = 'C100';
SELECT INDEX_NAME, MONITORING, USED, START_MONITORING
FROM V$OBJECT_USAGE
ORDER BY INDEX_NAME;
此时通常可以看到:
IDX_T_CODE 的 USED 变为 YESIDX_T_NOTE 仍为 NO说明:USED=NO 只表示监控开启以来未见使用,不代表该索引永远无用,生产环境建议覆盖完整业务周期后再判断。
确认无业务依赖后,可删除未使用索引:
DROP INDEX IDX_T_NOTE;
SELECT INDEX_NAME, TABLE_NAME
FROM USER_INDEXES
WHERE TABLE_NAME = 'T_IDX_MON';
清理完成后,建议关闭监控,避免额外开销:
ALTER INDEX IDX_T_CODE NOMONITORING USAGE;
若希望系统自动记录索引使用情况,可将参数设置为 1:
ALTER SYSTEM SET 'MONITOR_INDEX_FLAG' = 1 BOTH;
自动监控开启后,一般不能再执行手动的 MONITORING / NOMONITORING。业务运行一段时间后,可通过 V$OBJECT_USAGE 与 USER_INDEXES 对比,找出未被记录为已使用的普通索引,再评估是否删除。
如需清空监控视图后重新观察,可执行:
CALL SP_DYNAMIC_VIEW_DATA_CLEAR('V$OBJECT_USAGE');
测试结束后建议改回手动模式:
ALTER SYSTEM SET 'MONITOR_INDEX_FLAG' = 0 BOTH;
DROP TABLE T_IDX_MON PURGE;
通过 ALTER INDEX ... MONITORING USAGE 与 V$OBJECT_USAGE,可以较客观地识别长期未使用的二级索引。结合业务周期评估后再清理,有助于降低存储占用和 DML 维护成本,提升库的整体健康度。
文章
阅读量
获赞
