
在Oracle中,如何监控索引的使用状况?
在开发应用程序时,可能会建立很多索引,那么这些索引的使用到底怎么样,是否有些索引一直都没有用到过,在这种情况下就需要对这些索引进行监控,以便确定它们的使用情况,并为是否可以清除它们给出依据。
监控索引有两种方式:
1、直接监控索引的使用情况
(1)设置所要监控的索引:ALTER INDEX IDX_T_XX MONITORING USAGE;
(2)查看该索引有没有被使用:SELECT * FROM V$OBJECT_USAGE;
(3)关闭监控:ALTER INDEX IDX_T_XX NOMONITORING USAGE;
查询V$OBJECT_USAGE就可以知道数据库对索引的使用情况了。通过一段时间的监控,就可以确定哪些是无用的索引。另外,为了避免使用V$OBJECT_USAGE只能查询到当前用户下索引的监控情况,可以使用如下语句查询数据库中所有被监控索引的使用情况:
1 SELECT U.NAME OWNER,
2 IO.NAME INDEX_NAME,
3 T.NAME TABLE_NAME,
4 DECODE(BITAND(I.FLAGS, 65536), 0, 'NO', 'YES') MONITORING,
5 DECODE(BITAND(OU.FLAGS, 1), 0, 'NO', 'YES') USED,
6 OU.START_MONITORING START_MONITORING,
7 OU.END_MONITORING END_MONITORING
8 FROM SYS.USER$ U,
9 SYS.OBJ$ IO,
10 SYS.OBJ$ T,
11 SYS.IND$ I,
12 SYS.OBJECT_USAGE OU
13 WHERE I.OBJ# = OU.OBJ#
14 AND IO.OBJ# = OU.OBJ#
15 AND T.OBJ# = I.BO#
16 AND U.USER# = IO.OWNER#;
2、通过查看历史的执行计划,分析索引的使用情况
可以从视图DBA_HIST_SQL_PLAN中获取到数据库中所有索引的扫描次数情况,然后根据扫描次数和开发人员沟通是否需要保留索引。
1WITH TMP1 AS
2 (SELECT I.OWNER INDEX_OWNER,
3 I.TABLE_OWNER,
4 TABLE_NAME,
5 INDEX_NAME,
6 INDEX_TYPE,
7 (SELECT NB.CREATED
8 FROM DBA_OBJECTS NB
9 WHERE NB.OWNER = I.OWNER
10 AND NB.OBJECT_NAME = I.INDEX_NAME
11 AND NB.SUBOBJECT_NAME IS NULL
12 AND NB.OBJECT_TYPE = 'INDEX') CREATED,
13 (SUM(S.BYTES) / 1024 / 1024) INDEX_MB,
14 (SELECT COUNT(1)
15 FROM DBA_IND_COLUMNS DIC
16 WHERE DIC.INDEX_NAME = I.INDEX_NAME
17 AND DIC.TABLE_NAME = I.TABLE_NAME
18 AND DIC.INDEX_OWNER = I.OWNER) COUNT_INDEX_COLS
19 FROM DBA_SEGMENTS S, DBA_INDEXES I
20 WHERE I.INDEX_NAME = S.SEGMENT_NAME
21 AND I.OWNER = S.OWNER
22 AND S.OWNER NOT LIKE '%SYS%'
23 GROUP BY I.OWNER, I.TABLE_OWNER, TABLE_NAME, INDEX_NAME, INDEX_TYPE
24 HAVING SUM(S.BYTES) > 1024 * 1024),
25TMP2 AS
26 (SELECT INDEX_OWNER,
27 INDEX_NAME,
28 PLAN_OPERATION,
29 (SELECT MIN(TO_CHAR(NB.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD HH24:MI:SS'))
30 FROM DBA_HIST_SNAPSHOT NB
31 WHERE NB.SNAP_ID = V.MIN_SNAP_ID) MIN_DATE,
32 (SELECT MAX(TO_CHAR(NB.END_INTERVAL_TIME, 'YYYY-MM-DD HH24:MI:SS'))
33 FROM DBA_HIST_SNAPSHOT NB
34 WHERE NB.SNAP_ID = V.MAX_SNAP_ID) MAX_DATE,
35 COUNTS
36 FROM (SELECT D.OBJECT_OWNER INDEX_OWNER,
37 D.OBJECT_NAME INDEX_NAME,
38 D.OPERATION || ' ' || D.OPTIONS PLAN_OPERATION,
39 MIN(H.SNAP_ID) MIN_SNAP_ID,
40 MAX(H.SNAP_ID) MAX_SNAP_ID,
41 COUNT(1) COUNTS
42 FROM DBA_HIST_SQL_PLAN D, DBA_HIST_SQLSTAT H
43 WHERE D.OPERATION LIKE '%INDEX%'
44 AND D.SQL_ID = H.SQL_ID
45 GROUP BY D.OBJECT_OWNER, D.OBJECT_NAME, D.OPERATION, D.OPTIONS) V)
46SELECT A.TABLE_OWNER,
47 A.TABLE_NAME,
48 A.INDEX_OWNER,
49 A.INDEX_NAME,
50 A.CREATED,
51 A.INDEX_TYPE,
52 A.INDEX_MB,
53 A.COUNT_INDEX_COLS,
54 B.PLAN_OPERATION,
55 CASE
56 WHEN MIN_DATE IS NULL THEN
57 (SELECT MIN(TO_CHAR(NB.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD HH24:MI:SS'))
58 FROM DBA_HIST_SNAPSHOT NB)
59 ELSE
60 MIN_DATE
61 END AS MIN_DATE,
62 CASE
63 WHEN MAX_DATE IS NULL THEN
64 (SELECT MAX(TO_CHAR(NB.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD HH24:MI:SS'))
65 FROM DBA_HIST_SNAPSHOT NB)
66 ELSE
67 MAX_DATE
68 END AS MAX_DATE,
69 COUNTS
70 FROM TMP1 A
71 LEFT OUTER JOIN TMP2 B
72 ON (A.INDEX_OWNER = B.INDEX_OWNER AND A.INDEX_NAME = B.INDEX_NAME);
假设有如下的运行结果:

从图中可以看到有一个3.6G大的索引在13号到22号从没使用过,接下来,可以继续查询该索引是否是联合索引,创建是否合理,分析为何不走该索引,从而判断是否可以删除索引。
& 说明:
有关索引的监控过程可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2120752/
本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。

---------------优质麦课------------

详细内容可以添加麦老师微信或QQ私聊。

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用
● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/
● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
● QQ:646634621 QQ群:618766405
● 提供OCP、OCM和高可用部分最实用的技能培训
● 题目解答若有不当之处,还望各位朋友批评指正,共同进步
长按下图识别二维码或微信扫描下图二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。







