问题描述
嗨,
我可以删除索引并重新创建它们,而这些索引已被优化器选择用于sql执行并正在使用吗?
在删除数据库中的索引之前,我们是否需要关闭连接到数据库的应用程序?
还是可以在应用程序访问这些索引时删除索引?
请帮助我理解。
谢谢。
我可以删除索引并重新创建它们,而这些索引已被优化器选择用于sql执行并正在使用吗?
在删除数据库中的索引之前,我们是否需要关闭连接到数据库的应用程序?
还是可以在应用程序访问这些索引时删除索引?
请帮助我理解。
谢谢。
专家解答
有点违反直觉,你可以删除它们,但需要小心 * 之后 * .. 这是一个例子-我将创建一个带有索引的大表
我添加了提示以使他的查询运行速度非常慢-我将使用索引来扫描表中的每一行。所以现在我将在启用跟踪的情况下开始运行
在另一个会话中,我删除了索引。和 ..... 什么都没坏。
如果我查看跟踪文件,我看到:
这意味着我们 * 保持 * 使用索引,即使它被删除了。索引条目仍在磁盘上。
现在,如果我 (例如) 创建了一个重新使用这个空间的新表,我会从查询中得到一个错误。这里有几个视频显示了在不同但相关的场景中
回到您的问题-一种更安全,更简单的方法是两个阶段
1) 使索引不可见 (alter index IX不可见)
等待 (说) 一天,看看是否有任何查询出了严重的错误-如果这样做,只需使其再次可见或更改查询。一旦你开心了,以后再做
2) 下降指数
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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




