Mittwoch, 7. September 2016

Find indexes that possibly can be integrated into others

Following query returns all single column indexes (sci) of which the attribute is part of a multi column index (cmi) but not on first position. If the order of the cmi is changed such that the respective column is on the first position, the sci gets obsolete. This is only possible if the affected table is not queried with restrictions on the former first position column of the cmi.
with IND_COL_BASE
     as (select *
           from ALL_IND_COLUMNS
          where TABLE_OWNER not in ('SYS'
                                  , 'OPS$DEZA'
                                  , 'SYSTEM'
                                  , 'XDB'))
   , IND_COL_CNT
     as (  select TABLE_OWNER
                , TABLE_NAME
                , INDEX_OWNER
                , INDEX_NAME
                , count(*) as ANZ
             from IND_COL_BASE
         group by TABLE_OWNER
                , TABLE_NAME
                , INDEX_OWNER
                , INDEX_NAME)
   , IND_COL_1_ONLY
     as (select TABLE_OWNER
              , TABLE_NAME
              , INDEX_OWNER
              , INDEX_NAME
           from IND_COL_CNT
          where ANZ = 1)
   , IND_COL_P1
     as (select B.*
           from IND_COL_BASE B
                inner join IND_COL_1_ONLY C
                   on B.TABLE_OWNER = C.TABLE_OWNER
                  and B.TABLE_NAME = C.TABLE_NAME
                  and B.INDEX_OWNER = C.INDEX_OWNER
                  and B.INDEX_NAME = C.INDEX_NAME)
   , NON_UNIQUE_INDEXES
     as (select TABLE_OWNER
              , TABLE_NAME
              , OWNER
              , INDEX_NAME
           from ALL_INDEXES
          where UNIQUENESS = 'NONUNIQUE'
            and TABLE_OWNER not in ('SYS'
                                  , 'OPS$DEZA'
                                  , 'SYSTEM'
                                  , 'XDB'))
   , IND_COL_P1_NON_KEY
     as (select I.*
           from IND_COL_P1 I
                inner join NON_UNIQUE_INDEXES N
                   on I.TABLE_OWNER = N.TABLE_OWNER
                  and I.TABLE_NAME = N.TABLE_NAME
                  and I.INDEX_OWNER = N.OWNER
                  and I.INDEX_NAME = N.INDEX_NAME)
  select /*+ parallel(4) */
        *
    from IND_COL_P1_NON_KEY IC1
         inner join IND_COL_BASE IC
            on IC1.TABLE_OWNER = IC.TABLE_OWNER
           and IC1.TABLE_NAME = IC.TABLE_NAME
           and IC1.INDEX_OWNER = IC.INDEX_OWNER
           and IC1.COLUMN_NAME = IC.COLUMN_NAME
           and IC1.INDEX_NAME != IC.INDEX_NAME
           and IC1.COLUMN_POSITION != IC.COLUMN_POSITION
order by IC1.TABLE_OWNER asc
       , IC1.TABLE_NAME asc
       , IC1.INDEX_OWNER asc
       , IC1.INDEX_NAME asc
       , IC1.COLUMN_NAME asc;

Keine Kommentare:

Kommentar veröffentlichen