ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 索引列的usable和visible(二)

索引列的usable和visible(二)

原创 Linux操作系统 作者:realkid4 时间:2011-02-28 21:40:21 0 删除 编辑

 

上篇我们讨论了unusable的原理和使用,设置为unusable的索引,连带的DML操作会如何呢? 

 

 

注意下面的实验,笔者发现,如果此时对数据表进行DML操作,数据库会报错拒绝。

 

 

SQL> insert into stktestonhand (SEQ_NUMBER, FORMCODE, SERIESNUMBER_FROM, SERIESNUMBER_TO, TICKET_QUANTITY, REASONCODE_SEQ, CREATE_USER, CREATE_DATE, ALLOCATION_DATE)

  2  values (0,'000','100000000','1200000',32,43,'TEST',sysdate,sysdate);

 

insert into stktestonhand (SEQ_NUMBER, FORMCODE, SERIESNUMBER_FROM, SERIESNUMBER_TO, TICKET_QUANTITY, REASONCODE_SEQ, CREATE_USER, CREATE_DATE, ALLOCATION_DATE)

values (0,'000','100000000','1200000',32,43,'TEST',sysdate,sysdate)

 

ORA-01502: 索引 'NBSTEST.IND_STKTESTONHAND_COMP0' 或这类索引的分区处于不可用状态

 

 

这部分和我们原来对于unusable的理解存在差异,这个问题我们暂时留待下面解决。如果要恢复索引,需要重建对象。

 

SQL> alter index IND_STKTESTONHAND_COMP0 rebuild

  2  ;

 

Executed in 0.609 seconds

 

SQL> select index_name, table_name,UNIQUENESS,status, num_rows, VISIBILITY from user_indexes where index_name='IND_STKTESTONHAND_COMP0';

 

INDEX_NAME           TABLE_NAME      UNIQUENESS STATUS     NUM_ROWS VISIBILITY

-------------------- --------------- ---------- -------- ---------- ----------

IND_STKTESTONHAND_CO STKTESTONHAND   UNIQUE     VALID        200100 VISIBLE

MP0                                                                

 

 

下面我们实验invisible特性。

 

SQL> alter index ind_stktestonhand_comp0 invisible;

 

Executed in 0 seconds

 

SQL> select index_name, table_name,UNIQUENESS,status, num_rows, VISIBILITY from user_indexes where index_name='IND_STKTESTONHAND_COMP0';

 

INDEX_NAME           TABLE_NAME      UNIQUENESS STATUS     NUM_ROWS VISIBILITY

-------------------- --------------- ---------- -------- ---------- ----------

IND_STKTESTONHAND_CO STKTESTONHAND   UNIQUE     VALID        200100 INVISIBLE

MP0                                                                 

 

Executed in 0.062 seconds

 

 

此时,我们使用原有的SQL语句进行检索。

 

 

SQL> explain plan for select * from stktestonhand where SERIESNUMBER_FROM<=lpad('10000',10,'0') and SERIESNUMBER_TO>=lpad('10000',10,'0');

 

Executed in 0 seconds

 

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------

Plan hash value: 2311662756

-------------------------------------------------------------------------

| Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |               |   183 | 11346 |   588   (2)| 00:00:0

|*  1 |  TABLE ACCESS FULL| STKTESTONHAND |   183 | 11346 |   588   (2)| 00:00:0

--------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   1 - filter("SERIESNUMBER_FROM"<='0000010000' AND

              "SERIESNUMBER_TO">='0000010000')

 

Executed in 0.141 seconds

 

 

 

unusable一样,当索引被设置为invisible之后,Oracle优化器在生成执行计划的时候,是不会选择索引路径的。那么,invisible的索引是否和数据表还保持的DML同步呢?

 

 

SQL> insert into stktestonhand (SEQ_NUMBER, FORMCODE, SERIESNUMBER_FROM, SERIESNUMBER_TO, TICKET_QUANTITY, REASONCODE_SEQ, CREATE_USER, CREATE_DATE, ALLOCATION_DATE)

  2  values (0,'000','100000000','1200000',32,43,'TEST',sysdate,sysdate)

  3  ;

 

Executed in 0 seconds //对invisible索引的对象,是允许插入数据的。

 

(调用专门脚本,添加数据

SQL> select count(*) from stktestonhand;

 

  COUNT(*)

----------

    300100   //从原来的20万行,增加到30万

 

Executed in 0.047 seconds

 

 

SQL> select segment_name, segment_type,bytes,blocks from user_segments where segment_name='IND_STKTESTONHAND_COMP0';

 

SEGMENT_NAME    SEGMENT_TYPE            BYTES     BLOCKS

--------------- ------------------ ---------- ----------

IND_STKTESTONHA INDEX                11534336       1408

ND_COMP0                                     

 

 

Executed in 0.031 seconds

 

 

我们数据量从原来的20万增加到30万,同时索引对象的体积也变化到了11MB。说明,即使索引被invisible,不参与执行计划生成,但是会随着源数据表的DML操作而同步。

 

 

到此,我们得到了结论:invisible属性的作用就是让索引对象不参与进Oracle优化器执行计划生成过程,但是会随着数据表DML操作而更新。这点是与unusable的最大区别!

 

恢复属性,执行下面语句。

 

SQL> alter index ind_stktestonhand_comp0 visible;

 

Executed in 0.015 seconds

 

 

 

反思:站在Oracle的角度,想下为什么Oracle要提供这个invisible功能。如果没有这个属性,当我们需要暂时性的取消索引(调试、系统整理和实验),只能够删除索引或者unusable索引,让索引完全失效。这样虽然可以实现失效目的,但是带来一定的性能问题。

 

 

如果需要索引重新应用,相当于重建rebuild索引对象。我们反复说过,索引是一种有负担的对象,对一些海量数据表,重建数据表是很消耗时间和资源的,而且还伴随着一系列的锁操作。这对一些OLTP系统,特别是业务高峰期的系统,这种风险是不能轻易承受的。

 

invisible的出现,主要还是Oracle11g中对online特性支持的一种体现。索引虽然被invisible不可见了,但是只是一个标志的问题,索引本身还会和数据表维持联系。这样,进行索引失效切换动作,也会更加平滑安全。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-688136/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7688284