一、索引概述
如果一個數據表中存有海量的數據記錄,當對表執行指定條件的查詢時。常規的查詢方法會將所有的記錄都讀取出來,然后再把讀取的每一條記錄與查詢條件進行對比,最后返回滿足條件的記錄。這樣進行操作的時間開銷和I/O開銷都很大。對于這種情況,就可以考慮通過建立索引來減小系統開銷。
如果要在表中查詢指定的記錄,在沒有索引的情況下,必須遍歷整個表,而有了索引之后,只需要在索引中找到符合查詢條件的索引字段值,就可以通過保存在索引中的ROWID快速找到表中對應的記錄。例如,如果將表看做一本書,索引的作用類似于書中的目錄。在沒有目錄的情況下,要在書中查找指定的內容必須閱讀全文,而有了目錄之后,只需要通過目錄就可以快速找到包含所需內容的頁碼(相當于ROWID)。
用戶可以在Oracle中創建多種類型的索引,以適應各種表的特點。按照索引數據的存儲方式可以將索引分為B樹索引、位圖索引、反向鍵索引和基于函數的索引;按照索引列的唯一性可以分為唯一索引和非唯一索引;按照索引列的個數可以分為單列索引和復合索引。
建立和規劃索引時。必須選擇合適的表和列,如果選擇的表和列不合適,不僅無法提高查詢速度,反而會極大地降低DML操作的速度,所以建立索引必須注意以下幾點:
1.索引應該建立在WHERE子句頻繁引用列表上,如果在大表上頻繁使用某列或某幾個列作為條件執行索引操作,并且檢索行數低于總行數的15%,那么應該考慮在這些列上建立索引。
2.如果經常需要基于某列或者某幾個列排序操作,那么應該在這些列上建立索引可以加快數據排序速度。
3.限制表的索引個數。索引主要用于加快查詢速度,但會降低DML操作的速度。索引越多,DML操作速度越慢,尤其會極大地影響INSERT和DELETE操作的速度。因此,規劃索引時,必須仔細權衡查詢和DML的需求。
4.指定索引塊空間的使用參數。基于表建立索引時,Oracle會將相應表列數據添加到索引塊。為索引塊添加數據時,Oracle會按照PCTFREE參數在索引塊上預留部分空間,該預留空間是為將來的INSERT操作準備的。如果將來在表上執行大量INSERT操作,那么應該在建立索引時設置較大的PCTFREE。
5.將表和索引部署到相應的表空間,可以簡化表空間的管理;將表和索引部署到不同的表空間,可以提高訪問性能。
6.當在大表上建立索引時,使用NOLOGGING選項可以最小化重做記錄。使用NOLOGGING選項可以節省重做日志空間、降低索引建立時間、提高索引并行建立的性能。
7.不要在小表上建立索引。
8.為了提高多表連接的性能,應該在連接列上建立索引。
二、創建索引
在創建索引時,Oracle首先對將要建立索引的字段進行排序,然后將排序后的字段值和對應記錄的ROWID存儲在索引段中。建立索引可以使用CREATE INDEX語句,通常由表的所有者來建立索引。如果要以其他用戶身份建立索引,則要求用戶必須具有CREATE ANY INDEX系統權限或者相應表的INDEX對象權限。
1.建立B樹索引
B樹索引是Oralce數據庫中最常用的索引類型(也是默認的),它是以B樹結構組織并且存放索引數據的。默認情況下,B樹索引中的數據是以升序方式排序的。如果表包含的數據非常多,并且經常在WHERE字句中引用某列或某幾個列,則應該基于該列或這幾個列建立B樹索引。B樹索引由根節點塊、分支節點塊和葉子節點塊組成。其中主要數據都集中在葉子節點塊所指向的數據行。
根節點塊:索引頂級塊,它包含指向下一級節點的信息。
分支節點塊:它包含指向下一節點的信息。
葉子節點塊:通常也稱為葉子,它包含索引入口數據,索引入口包含索引列的值和記錄行對應的物理地址ROWID。
在B樹索引中無論用戶要搜索哪個分支的葉塊,都可以保證所經過的索引層次是相同的。Oracel采用這種方式的索引,可以確保無論索引條目位于何處,都只需花費相同的I/O即可獲取它,這就是為什么被稱為B樹索引。
如果在WHERE字句中要經常應用某列或者某幾列,應該基于這些列建立B樹索引。
2.建立位圖索引
索引的作用簡單地說就是能夠通過給定的索引列值,快速地找到相應的記錄。在B樹索引中,通過在索引中保存排序的索引列的值以及記錄的物理地址ROWID來實現快速查找。但是對于一些特殊的表,B樹索引的效率可能會降低。
例如在某個具有性別列的表中,該列的所用取值只能是男或女。如果在性別列上創建B樹索引,那么創建的B樹只有兩個分支。當列的基數很低時,為其建立B樹索引顯然不合適。“基數低”表示在索引列中,所有取值的數量比表中行的數量少。如“性別”只有兩個取值;再比如某個擁有10000行的表,它的一個列包含100個不同的取值,則該列仍然滿足低基數的要求,因為該列與該行數的比例為1%。Oracle推薦一個列的基數小于1%時,這些列不再適合建立B樹索引,而使用于位圖索引。
3.建立反向鍵索引
反向鍵索引是一個特殊類型的B樹索引,在順序遞增列上建立索引時非常有用。反向鍵索引的工作原理非常簡單,在存儲結構方面它與常規的B樹索引相同。然而,如果用戶使用序列在表中輸入記錄,則反向鍵索引首先指向每個列鍵值的字節,然后在反向后的新數據上進行索引。例如,如果用戶輸入的索引列為2011,則反向轉換后為1102;9527反向轉換后為7259.需要注意,剛才提及的兩個序列編號是遞增的,但是當進行反向鍵索引時確是非遞增的。這意味著如果將其添加到子葉節點,可能會在任意的子節點中進行。這樣就使得新數據在值的范圍上的分布通常比原來的有序數更均勻。