禁用并稍后启用Oracle中的所有表索引

时间:2020-03-06 14:40:54  来源:igfitidea点击:

如何在Oracle中的给定架构/数据库中禁用并稍后启用所有索引?

注意:这是为了使sqlldr运行更快。

解决方案

从这里:http://forums.oracle.com/forums/thread.jspa?messageID=2354075

更改会话设置skip_unusable_indexes = true;

更改索引your_index不可用;

确实要导入...

alter index your_index rebuild [online];

我们可以在Oracle中禁用约束,但不能禁用索引。有一个命令使索引变得不可更改,但是无论如何我们都必须重建索引,因此我可能只想编写一个脚本来删除并重建索引。我们可以使用user_indexes和user_ind_columns来获取模式的所有索引或者使用dbms_metadata:

select dbms_metadata.get_ddl('INDEX', u.index_name) from user_indexes u;

结合两个答案:

首先创建sql以使所有索引不可用:

alter session set skip_unusable_indexes = true;
select 'alter index ' || u.index_name || ' unusable;' from user_indexes u;

导入...

select 'alter index ' || u.index_name || ' rebuild online;' from user_indexes u;

如果使用的是非并行直接路径负载,则考虑并基准测试根本不删除索引,尤其是在索引仅覆盖少数列的情况下。 Oracle具有在直接路径负载上有效维护索引的机制。

否则,我也建议使索引不可用,而不要删除它们。意外不重新创建索引的机会更少。

将3个答案结合在一起:
(因为select语句不执行DDL)

set pagesize 0

alter session set skip_unusable_indexes = true;
spool c:\temp\disable_indexes.sql
select 'alter index ' || u.index_name || ' unusable;' from user_indexes u;
spool off
@c:\temp\disable_indexes.sql

导入...

select 'alter index ' || u.index_name || 
' rebuild online;' from user_indexes u;

请注意,这假设导入将在同一(sqlplus)会话中进行。
如果要调用" imp",它将在一个单独的会话中运行,因此我们需要使用" ALTER SYSTEM"而不是" ALTER SESSION"(并记住将参数放回找到的位置。

如果我们使用的是Oracle 11g,则可能还需要签出dbms_index_utl。

我们应该尝试sqlldr的SKIP_INDEX_MAINTENANCE参数。

这使得没有文件就无法使用索引:

DECLARE
  CURSOR  usr_idxs IS select * from user_indexes;
  cur_idx  usr_idxs% ROWTYPE;
  v_sql  VARCHAR2(1024);

BEGIN
  OPEN usr_idxs;
  LOOP
    FETCH usr_idxs INTO cur_idx;
    EXIT WHEN NOT usr_idxs%FOUND;

    v_sql:= 'ALTER INDEX ' || cur_idx.index_name || ' UNUSABLE';
    EXECUTE IMMEDIATE v_sql;
  END LOOP;
  CLOSE usr_idxs;
END;

重建将是相似的。