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





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