暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 使用时丢弃索引

ASKTOM 2019-06-28
308

问题描述

嗨,

我可以删除索引并重新创建它们,而这些索引已被优化器选择用于sql执行并正在使用吗?
在删除数据库中的索引之前,我们是否需要关闭连接到数据库的应用程序?
还是可以在应用程序访问这些索引时删除索引?

请帮助我理解。
谢谢。

专家解答

有点违反直觉,你可以删除它们,但需要小心 * 之后 * .. 这是一个例子-我将创建一个带有索引的大表

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)


我添加了提示以使他的查询运行速度非常慢-我将使用索引来扫描表中的每一行。所以现在我将在启用跟踪的情况下开始运行

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]


在另一个会话中,我删除了索引。和 ..... 什么都没坏。

如果我查看跟踪文件,我看到:

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
...
...


这意味着我们 * 保持 * 使用索引,即使它被删除了。索引条目仍在磁盘上。

现在,如果我 (例如) 创建了一个重新使用这个空间的新表,我会从查询中得到一个错误。这里有几个视频显示了在不同但相关的场景中





回到您的问题-一种更安全,更简单的方法是两个阶段

1) 使索引不可见 (alter index IX不可见)

等待 (说) 一天,看看是否有任何查询出了严重的错误-如果这样做,只需使其再次可见或更改查询。一旦你开心了,以后再做

2) 下降指数


文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论