DBAtlas · 数据库运维图谱

检测未使用的索引

Oracle

-- Start monitoring:
ALTER INDEX customer_city_idx MONITORING USAGE;
-- Check after a while (12c+, all schemas):
SELECT owner, index_name, used FROM dba_object_usage;

USED = NO 表示该索引在监控期间未被使用。使用 NOMONITORING USAGE 关闭监控。旧的 v$object_usage 只显示当前会话用户的索引,且自 12c 起已弃用。在 12.2+ 中,索引使用情况会自动记录在 DBA_INDEX_USAGE 中。

PostgreSQL

SELECT relname AS table, indexrelname AS index, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY relname;

idx_scan = 0 表示自上次重置统计信息以来该索引未被使用;不要删除 UNIQUE/PK 索引。

MySQL

SELECT * FROM sys.schema_unused_indexes;

必须启用 performance_schema,且服务器需已运行一段时间;UNIQUE 约束不在统计范围内。

SQL Server

SELECT OBJECT_NAME(i.object_id) AS table_name, i.name AS index_name
FROM sys.indexes i
LEFT JOIN sys.dm_db_index_usage_stats s
  ON i.object_id = s.object_id AND i.index_id = s.index_id
  AND s.database_id = DB_ID()
WHERE i.type_desc = 'NONCLUSTERED'
  AND COALESCE(s.user_seeks + s.user_scans + s.user_lookups, 0) = 0;

usage_stats 在服务器重启时会被重置;需留出足够的观察窗口。

MongoDB

db.customer.aggregate([{ $indexStats: {} }])
// Indexes with low/0 accesses.ops are candidates

accesses.ops 统计自 accesses.since 时间戳以来的访问次数;_id 索引无法删除。

Redis

# Not applicable: core Redis has no secondary indexes.
# If the RediSearch module is used, check statistics with FT.INFO <index>.

由于数据模型是键值型,不存在传统意义上的索引概念。

在 DBAtlas 中打开 →