电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

监视未使用索引


发布日期:2021/12/11
 

作者gototop

索引可以加快查询的速度但索引会占用许多存储空间在插入和删除行的时候索引还会引入额外的开销因此确保索引得到有效利用是我们很关注的一个问题在Oraclei之前要知道一个索引是否被使用是困难的而Oracle i中提供了一个有效的监控方法:ALTER INDEX MONITORING USAGE下面我讲详细说明如何使用该方法来鑒别未使用的索引

我们先通过一个例子具体说明ALTER INDEX MONITORING USAGE的使用方法

建测试表

create table test(id number()name varchar());

insert into test values(aaaaaaaa);

insert into test values();

insert into test values(aadfaaaa);

insert into test values(gototop);

insert into test values(shenzhen);

insert into test values(china);

commit;

alter table test add (constraint test_pk primary key (id));

查询v$object_usage(因为没有监视所以还看不到内容)

column index_name format a

column monitoring format a

column used format a

column start_monitoring format a

column end_monitoring format a

select index_namemonitoringusedstart_monitoringend_monitoring from v$object_usage;

SQL> l

* select index_namemonitoringusedstart_monitoringend_monitoring from v$object_usage

SQL> /

no rows selected

Elapsed: ::

开始监控索引的使用情况

SQL> alter index test_pk monitoring usage;

Index altered

Elapsed: ::

查询v$object_usage(可以看到正监视中)

SQL> select index_namemonitoringusedstart_monitoringend_monitoring from v$object_usage;

INDEX_NAME MONITORING USED START_MONITORING END_MONITORING

TEST_PK YES NO // ::

Elapsed: ::

使用索引进行查询

SQL> set autotrace on explain

SQL> select * from test where id = ;

ID NAME

Elapsed: ::

Execution Plan

SELECT STATEMENT Optimizer=CHOOSE

TABLE ACCESS (BY INDEX ROWID) OF TEST

INDEX (UNIQUE SCAN) OF TEST_PK (UNIQUE)

SQL> set autotrace off

SQL> /

ID NAME

Elapsed: ::

SQL>

从上我们可以看到确实使用了索引

查询v$object_usage(可以看到索引被使用过但目前还处于被监视过程中)

SQL> select index_namemonitoringusedstart_monitoringend_monitoring from v$object_usage;

INDEX_NAME MONITORING USED START_MONITORING END_MONITORING

TEST_PK YES YES // ::

Elapsed: ::

停止监视并查询v$object_usage

SQL> alter index test_pk nomonitoring usage;

Index altered

Elapsed: ::

SQL> select index_namemonitoringusedstart_monitoringend_monitoring from v$object_usage;

INDEX_NAME MONITORING USED START_MONITORING END_MONITORING

TEST_PK NO YES // :: // ::

Elapsed: ::

到此为止监视结束MONITORING为NOEND_MONITORING给出了时间戳

v$object_usage视图解释

从上面的例子中我们可以看出索引的监视信息都是存在在v$objec_usage视图中该视图的定义如下

CREATE OR REPLACE VIEW SYSV$OBJECT_USAGE

(

INDEX_NAME

TABLE_NAME

MONITORING

USED

START_MONITORING

END_MONITORING

)

AS

select ioname tname

decode(bitand(iflags ) NO YES)

decode(bitand(ouflags ) NO YES)

oustart_monitoring

ouend_monitoring

from sysobj$ io sysobj$ t sysind$ i sysobject_usage ou

where ioowner# = userenv(SCHEMAID)

and iobj# = ouobj#

and ioobj# = ouobj#

and tobj# = ibo#

/

COMMENT ON TABLE SYSV$OBJECT_USAGE IS

Record of index usage

/

GRANT SELECT ON SYSV$OBJECT_USAGE TO PUBLIC

/

下面是该视图列的描述

INDEX_NAME: sysobj$name 中的索引名字

TABLE_NAME: sysobj$obj$name 中的表名

MONITORING: YES (索引正在被监控) NO (索引没有被监控)

USED: YES (索引已经被使用过) NO (索引没有被使用过)

START_MONITORING: 开始监控的时间

END_MONITORING: 结束监控的时间

所有被使用过至少一次的索引都可以被监控并显示到这个视图中

监视数据库中所有索引的使用情况

生成开始/结束监视索引的SQL脚本

set heading off

set echo off

set feedback off

set pages

spool start_index_monitorsql

select alter index ||owner||||index_name|| monitoring usage;

from dba_indexes

where owner in (YOURPROD_DBOWNERLIST);

spool off

set heading on

set echo on

set feedback on

set heading off

set echo off

set feedback off

set pages

spool stop_index_monitorsql

select alter index ||owner||||index_name|| nomonitoring usage;

from dba_indexes

where owner in (YOURPROD_DBOWNERLIST);

spool off

set heading on

set echo on

set feedback on

进行监视并查询结果

在业务量比较多的一天上班时运行start_index_monitorsql下班前运行stop_index_monitorsql之后就可以在各用户自己的v$object_usage视图中看到该SCHEMA下的索引使用情况了

SQL> conn t/t

Connected

SQL> select index_nametable_nameused

from v$object_usage

where used=NO;

INDEX_NAME TABLE_NAME USED

TEST_PK TEST NO

row selected

SQL>

改进结果查寻方法

你也许已经注意到上面查询结果是需要我们单独查询各SCHEMA中的v$object_usage其实我们可以通过给v$object_usage视图添加一个owner列来创建一个可以存储所有SHCEMA的v$object_usage视图不妨叫做v$all_object_usage定义如下

CREATE OR REPLACE VIEW SYSV$ALL_OBJECT_USAGE

(

OWNER

INDEX_NAME

TABLE_NAME

MONITORING

USED

START_MONITORING

END_MONITORING

)

AS

select uname ioname tname

decode(bitand(iflags ) NO YES)

decode(bitand(ouflags ) NO YES)

oustart_mon

上一篇:性检查的简单快捷方法(利用Post方法和Timer)

下一篇:Data Server Scripts