Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Philip.

Asked: June 28, 2019 - 6:31 pm UTC

Last updated: July 02, 2019 - 6:38 am UTC

Version: 11.2.0.4

Viewed 1000+ times

You Asked

Hi,

Can I drop indexes and re-create them, while those indexes have been picked by optimizer for a sql execution and being used?
Do we need to shutdown the apps connected to the databases, before dropping indexes in a database?
Or can indexes be dropped while apps are accessing these indexes being dropped?

Please help me understand.
Thanks.

and Connor said...

Somewhat counter-intuitively you can drop them but need to be careful on what comes *after* that..Here's an example - I'll create a big table with an index

SQL> create table t as
  2  select d.* from dba_objects d,
  3   ( select 1 from dual connect by level <= 100 );

Table created.

SQL>  create index ix on t ( object_id );

Index created.

SQL> set autotrace traceonly explain
SQL> select /*+ index_rs_asc(t ix) */ max(owner)
  2  from t
  3  where object_id > 0 ;

Execution Plan
----------------------------------------------------------
Plan hash value: 2143077847

---------------------------------------------------------------------------------------------
| Id  | Operation                            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |      |     1 |    11 |  8268K  (1)| 00:05:23 |
|   1 |  SORT AGGREGATE                      |      |     1 |    11 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| T    |  8247K|    86M|  8268K  (1)| 00:05:23 |
|*  3 |    INDEX RANGE SCAN                  | IX   |  8247K|       | 18296   (1)| 00:00:01 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("OBJECT_ID">0)


I added the hint to make his query run really slow - I'm going to use the index to scan every row in the table. So now I'll start it running with a trace enabled

SQL> set autotrace off
SQL> exec dbms_monitor.session_trace_enable(waits=>true);

PL/SQL procedure successfully completed.

SQL> select /*+ index_rs_asc(t ix) */ max(owner)
  2  from t
  3  where object_id > 0 ;

[running]


and in another session I dropped the index. And.....nothing broke.

If I look at the trace file I see:

WAIT #1344857178368: nam='db file sequential read' ela= 203 file#=12 block#=20527 blocks=1 obj#=136229 tim=1349784362738
WAIT #1344857178368: nam='db file sequential read' ela= 187 file#=12 block#=20648 blocks=1 obj#=136229 tim=1349784363300
WAIT #1344857178368: nam='db file sequential read' ela= 191 file#=12 block#=20649 blocks=1 obj#=136229 tim=1349784363846
WAIT #1344857178368: nam='db file sequential read' ela= 178 file#=12 block#=20650 blocks=1 obj#=136229 tim=1349784364373
WAIT #1344857178368: nam='db file sequential read' ela= 172 file#=12 block#=20651 blocks=1 obj#=136229 tim=1349784364898
WAIT #1344857178368: nam='db file sequential read' ela= 188 file#=12 block#=20652 blocks=1 obj#=136229 tim=1349784365442
WAIT #1344857178368: nam='db file sequential read' ela= 197 file#=12 block#=20653 blocks=1 obj#=136229 tim=1349784366001
...
...


This means we *kept* using the index even though it was dropped. The index entries were still there on disk.

Now if I had (for example) created a new table that re-used this space, I'd get an error from the query. Here's a couple of videos showing that in a different but related scenario





Back to your question - a safer and easy way to handle this is do it two phases

1) make the index invisible (alter index IX invisible)

Wait for (say) a day to see if any queries goes terribly wrong - if they do, simply make it visible again or change the query. Once you're happy then at a later date do

2) drop index


Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, July 09, 2019 - 6:08 pm UTC

Thanks much Connor for your response.

For now i decided to create a new index with the 2 columns, and then drop the existing index with the one column.
And i am creating the index online with nologging and parallel.
And then alter the index with logging and noparallel.

More to Explore

Administration

Need more information on Administration? Check out the Administrators guide for the Oracle Database