5.索引的结构

2013-08-06 下午 星期二



------------------索引的结构------------------------


1、B树索引(平衡树索引),扫描索引就是平衡树的遍历。

  B树索引是传统的索引也是用的最多的索引,根据索引提供一行或者多个行的快速访问,

  通常只需要很少的IO次数就能找到正确的行。


2、需要掌握的要点:

 A 树的根节点、分支节点、叶子节点(叶子块)

 B 树的高度、树的层次(索引的平衡树的高度<=3的,根节点的层次为0,分之节点的层次为1,

   叶子节点的层次为2),max(level)+1=height

 C 范围查找时的搜索方法,涉及到叶子行使用的双向链表结构。在index range scan的时候,

   会搜索这个双向链表

 D 索引的唯一性特征:索引的叶子行必须是唯一的。

1 如果列值是唯一的,此时叶子行不存储ROWID,索引中列值是升序排列的。

2 如果列值是不唯一的,此时叶子行存储ROWID,索引中列值是升序排列,

 在列值的分组内,rowid再升序排列。


 E NULL值是不会被索引的

 F 叶子行=列值+rowid   如果列值是唯一的不重复的,叶子行=列值


3、创建索引的语法:

SQL> conn plsql/plsql

Connected.

SQL> create index ind_sht_nm on org_tab(org_short_name);


Index created.  --rowid一定会进入索引的,不管org_short_name是否有重复




创建唯一索引


SQL> create table tt1 as select * from all_objects;


Table created.


SQL> create unique index ind_obj_id on tt1(object_id);


Index created.  --这种情况rowid是不进索引的,因为unique关键字就决定了结构。



如果列值有重复,是不能强行创建unique索引。列值必须是唯一的才行。


SQL> create unique index ind_type_id on tt1(object_type);

create unique index ind_type_id on tt1(object_type)

                                  *

ERROR at line 1:

ORA-01452: cannot CREATE UNIQUE INDEX; duplicate keys found




分析索引:

SQL> exec dbms_stats.gather_index_stats(user,'ind_obj_id'); --直接分析索引


PL/SQL procedure successfully completed.


SQL> exec dbms_stats.gather_table_stats(user,'tt1',cascade=>true);  --分析表的时候将索引一起分析


PL/SQL procedure successfully completed.



索引空间——段的形式存在


select * from user_segments where segment_name='IND_OBJ_ID';


随着表数据的增加,索引也会不断增长。


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

       12    --当前的索引有12个extent。随着表数据不断增减,这个索引段也不会不断的增长



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


索引是不是也存在段空间碎片的问题?


1、delete操作,同时索引segment是不是也会有大量的空闲块生成,而且HWM会不会下降。


将表的数据删除一部分

SQL> select count(1) from user_extents where segment_name='TT1';


 COUNT(1)

----------

       20

SQL> delete from tt1 where rownum<=30000;


30000 rows deleted.


SQL> commit;


Commit complete.


SQL> select count(1) from user_extents where segment_name='TT1';   --HWM不会下降的


 COUNT(1)

----------

       20


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

       12     表的HWM没有下降,索引也没有下降



delete操作是回收碎片的空间。


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


======shrink操作回收磁盘空间,索引会不会跟着维护?===========


SQL> alter table tt1 enable row movement;


Table altered.


SQL> alter table tt1 shrink space;


Table altered.


SQL> select count(1) from user_extents where segment_name='TT1';


 COUNT(1)

----------

       17


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';  --shrink操作只能回收表的碎片,不能回收索引的空闲空间


 COUNT(1)

----------

       12


SQL> alter index ind_obj_id rebuild;  --索引必须要用重建的方法来回收碎片空间


Index altered.


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

        4


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


move操作回收碎片的时候 ,会不会同时维护索引?


SQL> insert into tt1 select * from all_objects;


41173 rows created.


SQL> commit;


Commit complete.


SQL> alter index ind_obj_id rebuild;  --重建索引


Index altered.



SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

       12


SQL> select count(1) from user_extents where segment_name='TT1';


 COUNT(1)

----------

       20


SQL> alter table tt1 move;  --进行move操作


Table altered.


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

       12


SQL> select count(1) from user_extents where segment_name='TT1';  --表HWM下降了,索引没有变化


 COUNT(1)

----------

       17


SQL> select index_name,status from user_indexes where index_name='IND_OBJ_ID';


INDEX_NAME                     STATUS

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

IND_OBJ_ID                     UNUSABLE  --此时索引的状态变成不可用了。



重建索引:

SQL> alter index ind_obj_id rebuild;


Index altered.


SQL> select index_name,status from user_indexes where index_name='IND_OBJ_ID';


INDEX_NAME                     STATUS

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

IND_OBJ_ID                     VALID


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

        4


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

如果索引是唯一的,是否也会失效? 答案:也会失效。


SQL> drop index ind_obj_id;


Index dropped.


SQL> create unique index ind_obj_id on tt1(object_id);


Index created.


SQL> truncate table tt1;


Table truncated.


SQL> insert into tt1 select * from all_objects;


41173 rows created.


SQL> commit;


Commit complete.


SQL> alter index ind_obj_id rebuild;


Index altered.


SQL> delete from tt1 where rownum<=30000;


30000 rows deleted.


SQL> commit;


Commit complete.


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

       12


SQL> select count(1) from user_extents where segment_name='TT1';


 COUNT(1)

----------

       20


SQL> alter table tt1 move;


Table altered.


SQL> select count(1) from user_extents where segment_name='TT1';


 COUNT(1)

----------

       17


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

       12


SQL> select index_name,status from user_indexes where index_name='IND_OBJ_ID';


INDEX_NAME                     STATUS

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

IND_OBJ_ID                     UNUSABLE


SQL> alter index ind_obj_id rebuild;


Index altered.


SQL> select index_name,status from user_indexes where index_name='IND_OBJ_ID';


INDEX_NAME                     STATUS

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

IND_OBJ_ID                     VALID


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

        4



实验结果看出unique索引,如果move操作后也是会失效的。




2、truncate操作,会维护索引


SQL> truncate table tt1;  --不仅可以维护表,还能维护索引


Table truncated.


SQL> select count(1) from user_extents where segment_name='TT1';


 COUNT(1)

----------

        1


SQL> select count(1) from user_extents where segment_name='IND_OBJ_ID';


 COUNT(1)

----------

        1





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章