谁在用这个索引
判断一个索引值不值得保留,先看有没有被用到:MySQL 有 sys 库里的未使用索引与冗余索引视图,PostgreSQL 用 pg_stat_user_indexes 的扫描计数。这些统计都是累计值,必须结合完整业务周期解读,看到 0 次不能直接删。
基本信息
| MySQL 未使用 | sys.schema_unused_indexes |
|---|---|
| MySQL 冗余 | sys.schema_redundant_indexes(被其他索引前缀覆盖等) |
| PostgreSQL | pg_stat_user_indexes 的 idx_scan 排序 |
| 统计窗口 | MySQL 自实例启动累计;PG 自统计重置以来累计 |
| 处置流程 | 先评估查询模式,再用不可见索引验证,最后删除 |
典型使用场景
- 大表索引过多导致写入变慢,梳理可下线项
- 加新索引前先检查有没有功能重复的旧索引
- 定期巡检,把未使用索引列成清单
- 结合索引体积与使用频率排优先级
- 配合不可见索引做删前的灰度验证
MySQL 查询
MySQL 查询
-- 实例启动以来没有被用过的索引
SELECT * FROM sys.schema_unused_indexes;
-- 冗余索引:被其他索引的前缀覆盖,或功能重复
SELECT * FROM sys.schema_redundant_indexes;PostgreSQL 查询
PostgreSQL 查询
-- 按扫描次数升序、索引体积降序,优先看又大又没被用到的
SELECT relname, indexrelname, idx_scan,
pg_size_pretty(pg_relation_size(indexrelid)) AS size
FROM pg_stat_user_indexes
ORDER BY idx_scan ASC, pg_relation_size(indexrelid) DESC
LIMIT 20;结果怎么读
| 指标 | 含义 | 怎么判断 |
|---|---|---|
| idx_scan | 索引被扫描的次数 | 长期为 0 才值得怀疑 |
| pg_relation_size | 索引占用的空间 | 又大又不用,优先级最高 |
| 唯一索引 | 承担唯一约束,0 次也不能删 | 先用约束视图排除 |
| 冗余索引 | 被其他索引最左前缀覆盖 | 保留覆盖能力更强的那个 |
| 统计起点 | 实例启动或统计重置之后 | 窗口越短,结论越不可靠 |
「未使用」不等于「可以删」:月度报表、季度结算这类周期长的查询在整个统计窗口里可能一次都没出现,删掉后到月末才发现缺索引。删除前先确认业务周期,并留好回退路径。
PostgreSQL 的统计在重启或统计重置后清零,视图也只覆盖用户创建的索引;把统计窗口与业务周期对齐之后,结论才可用。