Thursday, January 29, 2015

Index Monitoring Usage in Oracle Databases


In my career I saw when a VLDB or Old database (>10 Years) contains minimum 10 to 30 % Unused Index created .Its overall reduces database output. Its global cumulative loss is also huge.

How can impact it in database if index are extra in number. It can consume significant amount of CPU usage and memory too which finally can impact on write intensive database.

So its better to make regulation and stringent audit and review process before creation any index on a database.If already its created historically in database and database are mission critical then its very tough at the same time its very important to find out unused Index
to make database performance improvement.

You can use monitoring index feature of Oracle to find out which index are unused during some time window. For some time period we can activate its monitoring feature of all
index or suspected index. Once complete time window (Say for One Month) monitoring need to stop and then check weather its used or not in dba_object_usage table .
But which time window is best for index monitoring are very critical .Its depends upon application and best time could be year end Dec to Jan .Normally some critical report are run once in a year and some index are used that time only .To smoothen the year end process index are important .
Process of monitoring Index are describe below :

1. Alter index for Monitoring using below SQL

   alter index '<Index Name >' monitoring usage ;


2. Wait for time here say for One month .Its better for Dec to Feb .

3. Alter index for No Monitoring using below SQL

   alter index  '<Index Name >'  nomonitoring usage ;

4. Now check it in dba_object_usage table using below SQL

   SELECT * FROM dba_object_usage WHERE used = 'NO';

We can use below script for all index monitoring script


1. Create script for activation monitoring of all index and run it


set pages0

spool enable_monitoring.sql

select 'set echo on' from dual;

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

from user_indexes

order by 1;

spool disable_monitoring.sql

2. Wait for time here say for One month .It’s better for Dec to Feb .

3. Create script for disable No monitoring of all index and run it

select 'set echo on' from dual;

select 'alter index   ' || owner || '.' || index_name || '  nomonitoring usage ;' from user_indexes order by 1;

spool off

4. SELECT * FROM dba_object_usage WHERE used = 'NO';

5. OPTIMIZER_USE_INVISIBLE_INDEXES initialization parameter to TRUE at the session or system level

6. We can alter index invisible and wait for some time to see its effect on application .If it’s on then we can remove it from database safely.

   ALTER INDEX '<Index Name >' INVISIBLE;

   Create script for make index invisible

   select 'ALTER INDEX ' || owner || '.' || index_name || ' INVISIBLE;' FROM dba_object_usage WHERE used = 'NO';


7. Its helps us to check VISIBILITY check of index status.

  SELECT INDEX_NAME, VISIBILITY FROM USER_INDEXES WHERE INDEX_NAME in ('<Index Name >');

8. If its impact on application then make it visible once again using below SQL

    ALTER INDEX '<Index Name >' VISIBLE;




On EMP table I am creating one Index for showing its usage



SQL> create index idx_empeno on emp(empno);

SQL> alter index idx_empeno monitoring usage;

SQL> select * from emp;

  EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20

       7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30

2 row selected.


SQL> alter index idx_empeno monitoring usage;

SQL> select index_name, table_name, used from v$object_usage;


INDEX_NAME                     TABLE_NAME                     USE
------------------------------ ------------------------------ ---

idx_empeno                    EMP                            NO

1 row selected.

SQL> select * from emp where deptno = 30;

EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30

SQL> select index_name, table_name, used from v$object_usage;

INDEX_NAME                     TABLE_NAME                     USE
------------------------------ ------------------------------ ---
idx_empeno                    EMP                            NO

1 row selected.

SQL> select * from emp where empno < 7380;
     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
1 row selected.

SQL> select index_name, table_name, used from v$object_usage;

INDEX_NAME                     TABLE_NAME                     USE
------------------------------ ------------------------------ ---
idx_empeno                    EMP                            YES

1 row selected.