Oracle 的原理: 索引

    在表上建立索引,索引對於表,就像目錄對於書一樣,有了索引可以直接定位到表中的數據位置,大大的加快查找速度。索引可以減少磁盤IO,在邏輯上和物理上都獨立於表的數據,索引可以存放在任何磁盤上面,此外Oracle會自動維護索引。

 1.唯一索引、組合索引、反向鍵索引、函數索引、位圖索引

    索引可以分爲B樹(B-Tree)索引和位圖(Bitmap)索引,B樹索引又分爲唯一索引、組合索引、反向鍵索引、基於函數的索引。學過數據結構的都知道B樹,所有葉子節點都在同一個深度。每個節點塊可以包含關鍵字: 比如某個節點塊包含了關鍵字有 100,200 500,那麼他的葉子節點就有四個,數據範圍分別是  ...~100、100~200, 200~500 ,500~....。

創建索引最簡單的語法: CREATE INDEX [索引名]  ON [表名](表字段名)。  表名 user_indexes 、all_indexes可以看索引信息。表名user_ind_columns、all_ind_columns 查看索引的關聯信息。

索引碎片,指的是當索引關聯的數據如果被刪除,而索引信息還存在,那麼這個數據的索引就是無用的索引稱爲索引碎片,無用的信息佔用內存這樣會影響到Oracle性能。減少碎片的方法之一就是重建索引。

分析索引語句: ANALYZE INDEX [索引名] VALIDATE STRUCTURE;    然後查詢 INDEX_STATS查看pct_used 的索引碎片的多少。

首先先創建一個1300000個數據的表。來看看索引的效果。

--drop table salary_tbl;

create  table salary_tbl(
   employer_nm varchar(20),
   department varchar(20) not null,
   salary number not null,
   leader_nm varchar(20)
);
truncate table salary_tbl;
begin
 for i in  1..1300000
     loop
     insert into salary_tbl values('僱傭者'||i,'部門'||Mod(i,50),100+sqrt(i),'僱傭者'||Mod(i,20)); 
     if Mod(i,1000)=0 then 
       commit;
     end if;
   end loop;
end; 
/
commit;


新建索引,並查詢信息:

create index idx1 on salary_tbl(DEPARTMENT);
ANALYZE INDEX IDX1 VALIDATE STRUCTURE;     --分析索引
select s.name,s.pct_used,s.blocks from  INDEX_STATS s ;

此時是沒有索引碎片的,因爲指定的PCT_USED 最大值就是90.

刪除數據後再分析索引,查看索引信息:

此時的PCT_USED 使用率下降了,這就產生了索引碎片。想使使用率上升,其中一個方法就是重建索引:

ALTER INDEX IDX1 REBUILD;  -- ALTER INDEX [索引名] REBUILD
ANALYZE INDEX IDX1 VALIDATE STRUCTURE;
select s.name,s.pct_used,s.blocks from  INDEX_STATS s ;

重建索引後,使用率又上去了。

唯一索引:確保索引關聯的列上沒有重複值就叫做唯一索引,create  unique index [索引名] on  [表名](列名);  unique表示獨一無二,不能重複。索引關聯的字段值不能重複,否則會報錯,但是關聯字段允許有多個空值。

 

組合索引: 索引可以關聯多個字段,關聯多個字段的索引叫組合索引。create  index [索引名] on  [表名](列名1,列名2...),這樣可以加快查詢的語句是       select * from [table] where 列名1 = .. and 列名2... 這樣的語句。

 

反向鍵索引:Oracle爲了平均分散數據到各索引葉子節點上,避免某些葉子節點數據量太大而有些葉子節點過小問題,提供了反向鍵索引。鍵值逆序排序,和一般索引相比如果鍵值連續在一起的,這表示都放在同一個數據塊中,當要存取兩個相鄰的鍵值時,將會造成同時去搶同一個數據塊。反向鍵值的話,兩個相鄰的鍵值不會放到同一個數據塊中,就不會發生互搶了,但是由於鍵值的關係已經沒有了,葉子快沒有雙向連接的功能。所以,SQL語法條件是 = 時 ,才能產生最大的作用。

create  index [索引名] on  [表名](列名)  REVERES;

例如關聯的字段值是  1001      1002,  3211, 3212 ,3213 ,那麼反向鍵值就是 1001  2001 1123   2123  3123,用該值來建立索引。

 

函數索引:關聯的鍵值是通過函數計算的值,在where 函數(字段的時候)= ... 可以加快查詢速度。創建時需要有QUERY REWRITE權限,並且不能在 LOB類型的列上創建

      create  index [索引名] on  [表名](函數名(參數)) ;

 

位圖索引 (Bitmap索引) : Bitmap索引不屬於B-Tree索引,兩者有很大的區別。B-Tree索引鍵值後面跟着ROWID,而BitMap索引,鍵值後面跟着串位(String of bit),串位也就是'0'和‘1’組成的字符串。位圖索引能夠有效地節省索引空間,它適合創建在低基數列上,所謂低基數列指的就是取值非常少的字段。比如 性別=(‘男‘,’女’);   年級=(‘1',‘2’,‘3’) 像這樣的。

     create  bitmap  index [索引名] on  [表名](列名) ;

    

B-Tree索引 Bitmap索引
適合在索引鍵值比較多的時候,如學號、身份證等 適用於索引鍵值比較少的字段,如性別,血型,年級等
可以經常執行修改操作 執行修改操作的成本較高
對 ‘or’ 表達式很沒有效率 適用於 or 表達式的SQL語法 
適用於線上交易系統(OTP),經常變化的系統 適用於數據倉庫,資料量大,但不經常變化的系統

 

重建索引完整語法: ALTER INDEX index_name REBULID [Online] [NOLOGING] [COMPUTE STATISTICS]

Online:在線重建索引,在重建索引的過程中,還允許其他用戶進行增刪改操作,如果要建立的索引數量過大,那麼建立索引的時間會較長,在一般情況下,這段時間禁止對索引進行增刪改,可能會對業務造成影響。設成Online就可以避免這個。

NOLOGGING:表示在重建過程中產生最少的重做條目 Redo Entry.

COMPUTE STATISTICS: 重建過程中就生成了優化器所需的統計信息,不需要重建之後再手動的來analyze 或者 dbms_stats.

 

2.索引的分區:

       索引的分區有三種類型:局部分區索引、全局分區索引、全局非分區索引,分區索引可以在user_indexes 、user_ind_partitions表裏查找。

局部分區索引:在分區表上創建的索引,索引的分區範圍和表一致。create  index [索引名] on  [表名](字段)  local ;表怎麼分區,  局部分區索引就怎樣分區。

全局分區索引:create  index [索引名] on  [表名](字段)  global  Partition by .......:手動給索引進行自定義分區。表的分區狀況和索引分區沒有關係,索引的分配在哪個區上是自定義的。

全局非分區索引:在分區表上創建的全局普通索引,索引不進行分區。create  index [索引名] on  [表名](字段) global;

 

 

 

 

 

 

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