我们知道索引对于一个sql语句的执行性能有很大的影响。那么如果判断索引是否被使用以及使用的状态呢。
Oracle有专门的索引使用状况的跟踪,这并不是一个新功能,只不过12.2之后对此进行了改善。
12.2之前,为了跟踪索引信息,需要设置monitoring usage。 比如:
alter index <Index_Name> monitoring usage;
看一下设定后的状态。MONITORING列是YES ,表明处于监视的状态。
select * from v$object_usage;
INDEX_NAME TABLE_NAME MON USED START_MONITORING END_MONITORING
--------------- --------------- --- ---- ------------------- -------------------
I_TEST T_TEST YES NO 03/24/2021 09:17:19
然后通过定期观察v$object_usage来跟踪索引的使用状况。
select * from v$object_usage;
INDEX_NAME TABLE_NAME MON USED START_MONITORING END_MONITORING
--------------- --------------- --- ---- ------------------- -------------------
I_TEST T_TEST YES YES 03/24/2021 09:17:19
USED列为YES,表明该索引被使用。
如果经常发现索引没有被使用,那么就需要考虑是否重建更好的索引,或者删除了。
如果想关闭监视可以用nomonitoring usage。
SQL> alter index i_emp nomonitoring usage;
Index altered.
SQL> select * from v$object_usage;
INDEX_NAME TABLE_NAME MON USED START_MONITORING END_MONITORING
--------------- --------------- --- ---- ------------------- -------------------
I_TEST T_TEST NO YES 03/24/2021 09:17:19 03/24/2021 10:21:33
12.2之后, 索引跟踪的功能变成默认有效,不需要再单独设置。并且追加了索引的使用回数等信息。
还可以通过隐藏参数"_iut_stat_collection_type" 来改变索引跟踪的类型。
"_iut_stat_collection_type" 有2个参数。默认时SAMPLED 。这是个跟踪最少索引信息的类型。
还有一个参数是 ALL。 如果想要得到更加准确的索引信息,需要设为ALL。 需要注意的是,
如果"_iut_stat_collection_type" = ALL, 则会消耗一定的系统资源,建议只在需要的时候设置。
ALTER SYSTEM SET "_iut_stat_collection_type" = ALL;
设置完成以后,可以通过$INDEX_USAGE_INFO来跟踪索引的使用状况。 信息将会再15分钟更新一次。
SQL> DESC v$index_usage_info
Name Null? Type
----------------------------------------- -------- ----------------------------
INDEX_STATS_ENABLED NUMBER
INDEX_STATS_COLLECTION_TYPE NUMBER
ACTIVE_ELEM_COUNT NUMBER
ALLOC_ELEM_COUNT NUMBER
MAX_ELEM_COUNT NUMBER
FLUSH_COUNT NUMBER
TOTAL_FLUSH_DURATION NUMBER
LAST_FLUSH_TIME TIMESTAMP(3)
STATUS_MSG VARCHAR2(256)
CON_ID NUMBER
- INDEX_STATS_ENABLED 表示索引是否启用。1是启用。0是禁用。
- INDEX_STATS_COLLECTION_TYPE 表示是否对索引统计信息进行了采样。1 是采样。0表示跟踪所有使用信息。 1采样时默认的,开销较小,数据准确性较差。
- ACTIVE_ELEM_COUNT 上次刷新以来活跃的索引数。
- LAST_FLUSH_TIME 上次将统计信息刷到磁盘上的时间。
通过 LAST_FLUSH_TIME 的时间来判断索引信息已经刷新到磁盘上,然后可以通过dba_index_usage来确认更加详细的索引使用信息。
SQL> DESC dba_index_usage
Name Null? Type
----------------------------------------- -------- ----------------------------
OBJECT_ID NOT NULL NUMBER
NAME NOT NULL VARCHAR2(128)
OWNER NOT NULL VARCHAR2(128)
TOTAL_ACCESS_COUNT NUMBER
TOTAL_EXEC_COUNT NUMBER
TOTAL_ROWS_RETURNED NUMBER
BUCKET_0_ACCESS_COUNT NUMBER
BUCKET_1_ACCESS_COUNT NUMBER
BUCKET_2_10_ACCESS_COUNT NUMBER
BUCKET_2_10_ROWS_RETURNED NUMBER
BUCKET_11_100_ACCESS_COUNT NUMBER
BUCKET_11_100_ROWS_RETURNED NUMBER
BUCKET_101_1000_ACCESS_COUNT NUMBER
BUCKET_101_1000_ROWS_RETURNED NUMBER
BUCKET_1000_PLUS_ACCESS_COUNT NUMBER
BUCKET_1000_PLUS_ROWS_RETURNED NUMBER
LAST_USED DATE
- TOTAL_ACCESS_COUNT 索引被访问的总次数。
- TOTAL_EXEC_COUNT 索引参与的总执行量。
- TOTAL_ROWS_RETURNED 索引返回的总行数。
- LAST_USED 上次使用索引的时间。