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; beginfor i in 1..1300000loopinsert 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;
新建索引,并查詢信息:
此時是沒有索引碎片的,因為指定的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;
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的Oracle 的原理: 索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 原理: 视图,对视图进行增
- 下一篇: Oracle 原理 : 动态性能视图和数