oracle 11g较之前的版本,推出了很多新功能,其中一项就是不可见索引(invisible index)。
从Oracle 11g开始,可以创建不可见索引(invisible index)。优化器会忽略不可见的索引。
初始化参数optimizer_use_invisible_indexes决定是否使用invisible index,其默认值为false,即默认不使用invisible index。但如果在session级别或者system级别上将optimizer_use_invisible_indexes初始化参数设置为true,那么就可以使用invisible index。
与不可用索引不同,不可见索引在使用DML语句期间仍会得到维护。
Oracle引入不可见索引是有用途的,使索引不可见是使索引不可用或者删除索引的一种替代办法。使用不可见的索引,可以完成如下操作:
1、在删除索引之前测试对索引的删除,是否会产生影响。
2、对应用程序的特定操作或模块是使用临时索引结构,这样就不会影响整个应用程序。
当索引不可见时,优化器生成的执行计划不会使用该索引。删除索引时,可以先将索引修改为invisible,如果未发生性能下降的问题,则可以删除该索引。在表上新建索引时,可以先创建一个最初不可见的索引,然后执行测试,看索引的效率怎么样,最后确定是否使该索引可见,是否使用该索引。
可以查看dba_indexes、all_indexes、user_indexes视图的visibility字段来确定该索引是visible还是invisible。
下面做一些简单的测试
SQL> create table t as select * from user_objects;
Table created.
SQL> create index t_idx1 on t(object_name) invisible; --创建了一个invisible索引
Index created.
SQL> select INDEX_NAME,TABLE_OWNER,TABLE_NAME,VISIBILITY,STATUS from user_indexes where TABLE_NAME='T';
INDEX_NAME TABLE_OWNER TABLE_NAME VISIBILITY STATUS
---------- ----------- ---------- ----------- --------
T_IDX1 SCOTT T INVISIBLE VALID
SQL> set autot trace
SQL> select * from t where object_name='EMP';
Execution Plan
----------------------------------------------------------
Plan hash value: 1995730731
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 190 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T | 1 | 190 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_NAME"='EMP')
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
17 recursive calls
0 db block gets
33 consistent gets
0 physical reads
0 redo size
1328 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select /*+index(t t_idx1)*/ * from t where object_name='EMP';
Execution Plan
----------------------------------------------------------
Plan hash value: 1995730731
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 190 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T | 1 | 190 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_NAME"='EMP')
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
4 recursive calls
0 db block gets
9 consistent gets
0 physical reads
0 redo size
1328 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
从上面的两个执行计划看出,都没有走invisible索引(即使加了hint也被忽略了),均走全表扫描。
SQL> alter index t_idx1 visible; --将invisible索引修改为visible索引
Index altered.
SQL> select * from t where object_name='EMP';
Execution Plan
----------------------------------------------------------
Plan hash value: 2166198891
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 190 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 190 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX1 | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_NAME"='EMP')
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
1331 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
修改为visible索引后,执行计划走了T_IDX1索引。
下面测试参数optimizer_use_invisible_indexes对不可见索引的影响。这里仅在session级做测试。
SQL> alter index t_idx1 invisible; --将visible索引修改为invisible索引
Index altered.
SQL> set autot off
SQL> show parameter optimizer_use_invisible_indexes
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_use_invisible_indexes boolean FALSE
SQL>
SQL> alter session set optimizer_use_invisible_indexes=true; --将参数值修改为true
Session altered.
SQL> set autot trace
SQL> select * from t where object_name='EMP';
Execution Plan
----------------------------------------------------------
Plan hash value: 2166198891
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 190 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 190 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX1 | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_NAME"='EMP')
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
9 recursive calls
2 db block gets
9 consistent gets
0 physical reads
0 redo size
1331 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> alter session set optimizer_use_invisible_indexes=false; --将参数值修改为false
Session altered.
SQL> select * from t where object_name='EMP';
Execution Plan
----------------------------------------------------------
Plan hash value: 1995730731
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 190 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T | 1 | 190 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_NAME"='EMP')
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
5 recursive calls
0 db block gets
9 consistent gets
0 physical reads
0 redo size
1328 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> set autot off
经过测试,发现在会话级将optimizer_use_invisible_indexes参数设置为true,优化器会使用invisible索引。
在会话级将optimizer_use_invisible_indexes参数设置为false,优化器不会使用invisible索引。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24626891/viewspace-2129247/,如需转载,请注明出处,否则将追究法律责任。