一、索引概述
如果一個數(shù)據(jù)表中存有海量的數(shù)據(jù)記錄八千,當對表執(zhí)行指定條件的查詢時吗讶。常規(guī)的查詢方法會將所有的記錄都讀取出來,然后再把讀取的每一條記錄與查詢條件進行對比恋捆,最后返回滿足條件的記錄照皆。這樣進行操作的時間開銷和I/O開銷都很大。對于這種情況沸停,就可以考慮通過建立索引來減小系統(tǒng)開銷膜毁。
如果要在表中查詢指定的記錄,在沒有索引的情況下,必須遍歷整個表瘟滨,而有了索引之后候醒,只需要在索引中找到符合查詢條件的索引字段值,就可以通過保存在索引中的ROWID快速找到表中對應的記錄杂瘸。例如倒淫,如果將表看做一本書,索引的作用類似于書中的目錄胧沫。在沒有目錄的情況下昌简,要在書中查找指定的內(nèi)容必須閱讀全文,而有了目錄之后绒怨,只需要通過目錄就可以快速找到包含所需內(nèi)容的頁碼(相當于ROWID)纯赎。
用戶可以在Oracle中創(chuàng)建多種類型的索引,以適應各種表的特點南蹂。按照索引數(shù)據(jù)的存儲方式可以將索引分為B樹索引犬金、位圖索引、反向鍵索引和基于函數(shù)的索引六剥;按照索引列的唯一性可以分為唯一索引和非唯一索引晚顷;按照索引列的個數(shù)可以分為單列索引和復合索引。
建立和規(guī)劃索引時疗疟。必須選擇合適的表和列该默,如果選擇的表和列不合適,不僅無法提高查詢速度策彤,反而會極大地降低DML操作的速度栓袖,所以建立索引必須注意以下幾點:
1.索引應該建立在WHERE子句頻繁引用列表上,如果在大表上頻繁使用某列或某幾個列作為條件執(zhí)行索引操作店诗,并且檢索行數(shù)低于總行數(shù)的15%裹刮,那么應該考慮在這些列上建立索引。
2.如果經(jīng)常需要基于某列或者某幾個列排序操作庞瘸,那么應該在這些列上建立索引可以加快數(shù)據(jù)排序速度捧弃。
3.限制表的索引個數(shù)。索引主要用于加快查詢速度擦囊,但會降低DML操作的速度违霞。索引越多,DML操作速度越慢瞬场,尤其會極大地影響INSERT和DELETE操作的速度葛家。因此,規(guī)劃索引時泌类,必須仔細權(quán)衡查詢和DML的需求癞谒。
4.指定索引塊空間的使用參數(shù)底燎。基于表建立索引時弹砚,Oracle會將相應表列數(shù)據(jù)添加到索引塊双仍。為索引塊添加數(shù)據(jù)時,Oracle會按照PCTFREE參數(shù)在索引塊上預留部分空間桌吃,該預留空間是為將來的INSERT操作準備的朱沃。如果將來在表上執(zhí)行大量INSERT操作,那么應該在建立索引時設(shè)置較大的PCTFREE茅诱。
5.將表和索引部署到相應的表空間逗物,可以簡化表空間的管理;將表和索引部署到不同的表空間瑟俭,可以提高訪問性能翎卓。
6.當在大表上建立索引時,使用NOLOGGING選項可以最小化重做記錄摆寄。使用NOLOGGING選項可以節(jié)省重做日志空間失暴、降低索引建立時間、提高索引并行建立的性能微饥。
7.不要在小表上建立索引逗扒。
8.為了提高多表連接的性能,應該在連接列上建立索引欠橘。
二矩肩、創(chuàng)建索引
在創(chuàng)建索引時,Oracle首先對將要建立索引的字段進行排序肃续,然后將排序后的字段值和對應記錄的ROWID存儲在索引段中黍檩。建立索引可以使用CREATE INDEX語句,通常由表的所有者來建立索引痹升。如果要以其他用戶身份建立索引建炫,則要求用戶必須具有CREATE ANY INDEX系統(tǒng)權(quán)限或者相應表的INDEX對象權(quán)限畦韭。
1.建立B樹索引
B樹索引是Oralce數(shù)據(jù)庫中最常用的索引類型(也是默認的)疼蛾,它是以B樹結(jié)構(gòu)組織并且存放索引數(shù)據(jù)的。默認情況下艺配,B樹索引中的數(shù)據(jù)是以升序方式排序的察郁。如果表包含的數(shù)據(jù)非常多,并且經(jīng)常在WHERE字句中引用某列或某幾個列转唉,則應該基于該列或這幾個列建立B樹索引皮钠。B樹索引由根節(jié)點塊、分支節(jié)點塊和葉子節(jié)點塊組成赠法。其中主要數(shù)據(jù)都集中在葉子節(jié)點塊所指向的數(shù)據(jù)行麦轰。
根節(jié)點塊:索引頂級塊,它包含指向下一級節(jié)點的信息。
分支節(jié)點塊:它包含指向下一節(jié)點的信息款侵。
葉子節(jié)點塊:通常也稱為葉子末荐,它包含索引入口數(shù)據(jù),索引入口包含索引列的值和記錄行對應的物理地址ROWID新锈。
在B樹索引中無論用戶要搜索哪個分支的葉塊甲脏,都可以保證所經(jīng)過的索引層次是相同的。Oracel采用這種方式的索引妹笆,可以確保無論索引條目位于何處块请,都只需花費相同的I/O即可獲取它,這就是為什么被稱為B樹索引拳缠。
如果在WHERE字句中要經(jīng)常應用某列或者某幾列墩新,應該基于這些列建立B樹索引。
2.建立位圖索引
索引的作用簡單地說就是能夠通過給定的索引列值脊凰,快速地找到相應的記錄抖棘。在B樹索引中,通過在索引中保存排序的索引列的值以及記錄的物理地址ROWID來實現(xiàn)快速查找狸涌。但是對于一些特殊的表切省,B樹索引的效率可能會降低。
例如在某個具有性別列的表中帕胆,該列的所用取值只能是男或女朝捆。如果在性別列上創(chuàng)建B樹索引,那么創(chuàng)建的B樹只有兩個分支懒豹。當列的基數(shù)很低時芙盘,為其建立B樹索引顯然不合適×郴啵“基數(shù)低”表示在索引列中儒老,所有取值的數(shù)量比表中行的數(shù)量少。如“性別”只有兩個取值记餐;再比如某個擁有10000行的表驮樊,它的一個列包含100個不同的取值,則該列仍然滿足低基數(shù)的要求片酝,因為該列與該行數(shù)的比例為1%囚衔。Oracle推薦一個列的基數(shù)小于1%時,這些列不再適合建立B樹索引雕沿,而使用于位圖索引练湿。
3.建立反向鍵索引
反向鍵索引是一個特殊類型的B樹索引,在順序遞增列上建立索引時非常有用审轮。反向鍵索引的工作原理非常簡單肥哎,在存儲結(jié)構(gòu)方面它與常規(guī)的B樹索引相同辽俗。然而,如果用戶使用序列在表中輸入記錄篡诽,則反向鍵索引首先指向每個列鍵值的字節(jié)榆苞,然后在反向后的新數(shù)據(jù)上進行索引。例如霞捡,如果用戶輸入的索引列為2011坐漏,則反向轉(zhuǎn)換后為1102;9527反向轉(zhuǎn)換后為7259.需要注意碧信,剛才提及的兩個序列編號是遞增的赊琳,但是當進行反向鍵索引時確是非遞增的。這意味著如果將其添加到子葉節(jié)點砰碴,可能會在任意的子節(jié)點中進行躏筏。這樣就使得新數(shù)據(jù)在值的范圍上的分布通常比原來的有序數(shù)更均勻。