oracle查询某数据库用户下哪些表的索引没有被使用到?

1. 开启所有索引的监控

sql 复制代码
-- 为指定用户下的所有索引开启监控
BEGIN
  FOR idx IN (SELECT owner, index_name FROM dba_indexes WHERE owner = 'YOUR_SCHEMA') 
  LOOP
    EXECUTE IMMEDIATE 'ALTER INDEX ' || idx.owner || '.' || idx.index_name || ' MONITORING USAGE';
  END LOOP;
END;
/

2. 运行一段时间后检查使用情况

sql 复制代码
-- 查看监控结果(需要DBA权限)
SELECT 
    u.owner,
    u.index_name,
    i.table_name,
    u.monitoring,
    u.used,
    u.start_monitoring,
    u.end_monitoring,
    i.index_type,
    i.uniqueness,
    i.status
FROM v$object_usage u
JOIN dba_indexes i ON u.index_name = i.index_name AND u.owner = i.owner
WHERE u.owner = 'YOUR_SCHEMA'
  AND u.used = 'NO'  -- 未使用的索引
ORDER BY i.table_name, u.index_name;

3. 关闭监控

sql 复制代码
-- 监控完成后关闭监控
BEGIN
  FOR idx IN (SELECT owner, index_name FROM dba_indexes WHERE owner = 'YOUR_SCHEMA') 
  LOOP
    EXECUTE IMMEDIATE 'ALTER INDEX ' || idx.owner || '.' || idx.index_name || ' NOMONITORING USAGE';
  END LOOP;
END;
/

4.查询AWR中索引使用统计(需要AWR许可)--推荐使用,可以获取哪些索引使用频繁最高,哪些索引使用频繁最低,适用于生产慢SQL优化

sql 复制代码
-- 查看过去N天内索引在AWR中的使用情况
SELECT 
    d.object_owner,
    d.object_name as index_name,
    t.table_name,
    COUNT(DISTINCT d.sql_id) as sql_count,
    COUNT(*) as plan_line_count,
    MIN(d.timestamp) as first_seen,
    MAX(d.timestamp) as last_seen
FROM dba_hist_sql_plan d
JOIN dba_indexes i ON d.object_owner = i.owner AND d.object_name = i.index_name
JOIN dba_tables t ON i.table_owner = t.owner AND i.table_name = t.table_name
WHERE d.object_owner = 'YOUR_SCHEMA'
  AND d.object_type = 'INDEX'
  AND d.timestamp > SYSDATE - 30  -- 最近30天
GROUP BY d.object_owner, d.object_name, t.table_name
ORDER BY sql_count ASC;  -- 使用次数少的排在前面

5.从未在AWR中出现的索引(可能从未使用)--推荐使用,用于优化生产无效索引

sql 复制代码
-- 找出从未在AWR执行计划中出现的索引
SELECT 
    i.owner,
    i.index_name,
    i.table_name,
    i.index_type,
    i.uniqueness,
    i.status,
    i.num_rows,
    i.leaf_blocks
FROM dba_indexes i
LEFT JOIN (
    SELECT DISTINCT object_owner, object_name
    FROM dba_hist_sql_plan
    WHERE object_type = 'INDEX'
      AND timestamp > SYSDATE - 90  -- 最近90天
) p ON i.owner = p.object_owner AND i.index_name = p.object_name
WHERE i.owner = 'YOUR_SCHEMA'
  AND p.object_name IS NULL  -- 从未出现在AWR中
  AND i.index_type NOT IN ('LOB', 'DOMAIN')  -- 排除特殊类型索引
ORDER BY i.table_name, i.index_name;
相关推荐
这个DBA有点耶15 小时前
VLDB 2026核心议题解读:当负载被AI改写,数据库的内核该往哪走?
数据库·架构·aigc
敲代码的嘎仔16 小时前
自己设计了一个兑换码算法:自增ID + Base32转码 + 按位加权签名 + 异或混淆,面试被追问细节时终于不用慌了
java·数据库·mysql·算法·微服务·面试·职场和发展
shirsl16 小时前
数据开发实时项目问题整理
数据库·sql·big data
bbq粉刷匠16 小时前
数据库设计实践
数据库
java_logo16 小时前
Docker 部署 ClickHouse Server:轻松搭建列式 OLAP 分析数据库平台
数据库·clickhouse·docker·私有化部署·olap·列式数据库·轩辕镜像
盛世宏博智慧档案17 小时前
高速 ETC 门架外场机房温湿度远程监测解决方案
服务器·数据库·php·高度·高速·温湿度
—Miss. Z—17 小时前
计算机三级数据库技术—应用题2️⃣
数据库·mysql
PrudentWoo17 小时前
PostgreSQL 12 登录失败:role “postgres“ is not permitted to log in 的排查与修复
数据库·postgresql
这个DBA有点耶17 小时前
临时表从4.7秒到0.12秒:不是所有Using temporary都需要优化
数据库·mysql·代码规范
天衍四九-17 小时前
排查慢SQL用explain分析执行计划,主要关注哪些字段?
数据库·sql