時間:2015-06-28 00:00:00 來源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評論(0)
邏輯上:
Single column 單行索引
Concatenated 多行索引
Unique 唯一索引
NonUnique 非唯一索引
Function-based函數(shù)索引
Domain 域索引
物理上:
Partitioned 分區(qū)索引
NonPartitioned 非分區(qū)索引
B-tree:
Normal 正常型B樹
Rever Key 反轉型B樹
Bitmap 位圖索引
索引結構:
B-tree:
適合與大量的增、刪、改(OLTP);
不能用包含OR操作符的查詢;
適合高基數(shù)的列(唯一值多)
典型的樹狀結構;
每個結點都是數(shù)據(jù)塊;
大多都是物理上一層、兩層或三層不定,邏輯上三層;
葉子塊數(shù)據(jù)是排序的,從左向右遞增;
在分支塊和根塊中放的是索引的范圍;
Bitmap:
適合與決策支持系統(tǒng);
做UPDATE代價非常高;
非常適合OR操作符的查詢;
基數(shù)比較少的時候才能建位圖索引;
樹型結構:
索引頭
開始ROWID,結束ROWID(先列出索引的最大范圍)
BITMAP
每一個BIT對應著一個ROWID,它的值是1還是0,如果是1,表示著BIT對應的ROWID有值;
B*tree索引的話通常在訪問小數(shù)據(jù)量的情況下比較適用,比如你訪問不超過表中數(shù)據(jù)的5%,當然這只是個相對的比率,適用于一般的情況。bitmap的話在數(shù)據(jù)倉庫中使用較多,用于低基數(shù)列,比如性別之類重復值很多的字段,基數(shù)越小越好。
B* 樹索引
這些是我所說的 " 傳統(tǒng) " 索引。到目前為止,這是 Oracle 和大多數(shù)其他數(shù)據(jù)庫中最常用的索引。 B* 樹的構造類似于二叉樹,能根據(jù)鍵提供一行或一個行集的快速訪問,通常只需很少的讀操作就能找到正確的行。不過,需要注意重要的一點, " B* 樹 " 中的 " B " 不代表二叉( binary ),而代表平衡( b alanced )。B* 樹索引并不是一顆二叉樹,這一點在介紹如何在磁盤上物理地存儲 B* 樹時就會了解到。 B* 樹索引有以下子類型:
索引組織表( index organized table ):索引組織表以 B* 樹結構存儲。堆表的數(shù)據(jù)行是以一種無組織的方式存儲的(只要有可用的空間,就可以放數(shù)據(jù)),而 IOT 與之不同, IOT 中的數(shù)據(jù)要按主鍵的順序存儲和排序。對應用來說, IOT 表現(xiàn)得與 " 常規(guī) " 表并無二致;需要使用 SQL 來正確地訪問 IOT 。 IOT 對信息獲取、空間系統(tǒng)和 OLAP 應用最為有用。 IOT 在上一章已經(jīng)詳細地討論過。
B*樹聚簇索引( B*tree cluster index )這些是傳統(tǒng) B* 樹索引的一個變體(只是稍有變化)。 B* 樹聚簇索引用于對聚簇鍵建立索引(見第 11. 章中 " 索引聚簇表 " 一節(jié)),所以這一章不再討論。在傳統(tǒng) B* 樹中 ,鍵都指向一行;而 B* 樹聚簇不同,一個聚簇鍵會指向一個塊,其中包含與這個聚簇鍵相關的多行。
降序索引( descending index ):降序索引允許數(shù)據(jù)在索引結構中按 " 從大到小 " 的順序(降序)排序,而不是按 " 從小到大 " 的順序(升序)排序。我們會解釋為什么降序索引很重要,并說明降序索引如何工作。
反向鍵索引( reverse key index ):這也是 B* 樹索引,只不過鍵中的字節(jié)會 " 反轉 " 。利用反向鍵索引,如果索引中填充的是遞增的值,索引條目在索引中可以得到更均勻的分布。例如,如果使用一個序列來生成主鍵,這個序列將生成諸如 987500 、 987501 、 987502 等值。這些值是順序的,所以倘若使用一 個傳統(tǒng)的 B* 樹索引,這些值就可能放在同一個右側塊上,這就加劇了對這一塊的競爭。利用反向鍵, Oracl e則會邏輯地對 205789 、 105789 、 005789 等建立索引。 Oracle 將數(shù)據(jù)放在索引中之前,將先 把所存儲數(shù)據(jù)的字節(jié)反轉,這樣原來可能在索引中相鄰放置的值在字節(jié)反轉之后就會相距很遠。通過反轉字節(jié),對索引的插入就會分布到多個塊上。
#p#副標題#e#
位圖索引( bitmap index )
在一顆 B* 樹中,通常索引條目和行之間存在一種一對一的關系:一個 索引條目就指向一行。而對于位圖索引,一個索引條目則使用一個位圖同時指向多行。位圖索引適用于高度重復而且通常只讀的數(shù)據(jù)(高度重復是指相對于表中的總行數(shù),數(shù)據(jù)只有很少的幾個不同值)。考慮在一 個有 100 萬行的表中,每個列只有 3 個可取值: Y 、 N 和 NULL 。舉例來說,如果你需要頻繁地統(tǒng)計多少行有值Y ,這就很適合建立位圖索引。不過并不是說如果這個表中某一列有 11.000 個不同的值就不能建立位圖索引,這一列當然也可以建立 位圖索引。在一個 OLTP 數(shù)據(jù)庫中,由于存在并發(fā)性相關的問題,所以不能考慮使用位圖索引(后面我們就會討論這一點)。注意,位圖索引要求使用 Oracle 企業(yè)版或個人版。
位圖聯(lián)結索引( bitmap join index ):這為索引結構(而不是表)中的數(shù)據(jù)提供了一種逆規(guī)范化的 方法。例如,請考慮簡單的 EMP 和 DEPT 表。有人可能會問這樣一個問題: " 多少人在位于波士頓的部門工作 ?" EMP 有一個指向 DEPT 的外鍵,要想統(tǒng)計 LOC 值為 Boston 的部門中的員工人數(shù),通常必須完成表聯(lián)結,將 LOC 列聯(lián)結至 EMP 記錄來回答這個問題。通過使用位圖聯(lián)結索引,則可以在 EMP 表上對 LOC 列建立索引 。
基于函數(shù)的索引( function-based index )
這些就是 B* 樹索引或位圖索引,它將一個函數(shù)計算得到的結果存儲在行的列中,而不是存儲列數(shù)據(jù)本身??梢园鸦诤瘮?shù)的索引看作一個虛擬列(或派生列)上的索引,換句話說,這個列并不物理存儲在表中?;诤瘮?shù)的索引可以用于加快形如 SELECT * FROM T W HERE FUNCTION(DATABASE_COLUMN) = SAME_VALUE 這樣的查詢,因為值 FUNCTION(DATABASE_COLUMN) 已經(jīng)提前計算并存儲在索引中。
應用域索引( application domain index )
應用域索引是你自己構建和存儲的索引,可能存儲在Oracle 中,也可能在 Oracle 之外。你要告訴優(yōu)化器索引的選擇性如何,以及執(zhí)行的開銷有多大,優(yōu)化器則會根據(jù)你提供的信息來決定是否使用你的索引。 Oracle 文本索引就是應用域索引的一個例子;你也可 以使用構建 Oracle 文本索引所用的工具來建立自己的索引。需要指出,這里創(chuàng)建的 " 索引 " 不需要使用傳統(tǒng)的索引結構。例如, Oracle 文本索引就使用了一組表來實現(xiàn)其索引概念。
首先,我們要確定數(shù)據(jù)庫運行在何種優(yōu)化模式下,相應的參數(shù)是:optimizer_mode??稍趕vrmgrl中運行"show parameter optimizer_mode"來查看。ORACLE V7以來缺省的設置應是"choose",即如果對已分析的表查詢的話選擇CBO,否則選擇RBO。如果該參數(shù)設為"rule",則不論表是否分析過,一概選用RBO,除非在語句中用hint強制。
查找原因的步驟
首先,我們要確定數(shù)據(jù)庫運行在何種優(yōu)化模式下,相應的參數(shù)是:optimizer_mode??稍趕vrmgrl中運行"show parameter optimizer_mode"來查看。ORACLE V7以來缺省的設置應是"choose",即如果對已分析的表查詢的話選擇CBO,否則選擇RBO。如果該參數(shù)設為"rule",則不論表是否分析過,一概選用RBO,除非在語句中用hint強制。
其次,檢查被索引的列或組合索引的首列是否出現(xiàn)在PL/SQL語句的WHERE子句中,這是"執(zhí)行計劃"能用到相關索引的必要條件。
第三,看采用了哪種類型的連接方式。ORACLE的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。在兩張表連接,且內(nèi)表的目標列上建有索引時,只有Nested Loop才能有效地利用到該索引。SMJ即使相關列上建有索引,最多只能因索引的存在,避免數(shù)據(jù)排序過程。HJ由于須做HASH運算,索引的存在對數(shù)據(jù)查詢速度幾乎沒有影響。
第四,看連接順序是否允許使用相關索引。假設表emp的deptno列上有索引,表dept的列deptno上無索引,WHERE語句有emp.deptno=dept.deptno條件。在做NL連接時,emp做為外表,先被訪問,由于連接機制原因,外表的數(shù)據(jù)訪問方式是全表掃描,emp.deptno上的索引顯然是用不上,最多在其上做索引全掃描或索引快速全掃描。
第五,是否用到系統(tǒng)數(shù)據(jù)字典表或視圖。由于系統(tǒng)數(shù)據(jù)字典表都未被分析過,可能導致極差的"執(zhí)行計劃"。但是不要擅自對數(shù)據(jù)字典表做分析,否則可能導致死鎖,或系統(tǒng)性能下降。
第六,索引列是否函數(shù)的參數(shù)。如是,索引在查詢時用不上。
第七,是否存在潛在的數(shù)據(jù)類型轉換。如將字符型數(shù)據(jù)與數(shù)值型數(shù)據(jù)比較,ORACLE會自動將字符型用to_number()函數(shù)進行轉換,從而導致第六種現(xiàn)象的發(fā)生。
第八,是否為表和相關的索引搜集足夠的統(tǒng)計數(shù)據(jù)。對數(shù)據(jù)經(jīng)常有增、刪、改的表最好定期對表和索引進行分析,可用SQL語句"analyze table xxxx compute statistics for all indexes;"。ORACLE掌握了充分反映實際的統(tǒng)計數(shù)據(jù),才有可能做出正確的選擇。
第九,索引列的選擇性不高。
我們假設典型情況,有表emp,共有一百萬行數(shù)據(jù),但其中的emp.deptno列,數(shù)據(jù)只有4種不同的值,如10、20、30、40。雖然emp數(shù)據(jù)行有很多,ORACLE缺省認定表中列的值是在所有數(shù)據(jù)行均勻分布的,也就是說每種deptno值各有25萬數(shù)據(jù)行與之對應。假設SQL搜索條件DEPTNO=10,利用deptno列上的索引進行數(shù)據(jù)搜索效率,往往不比全表掃描的高,ORACLE理所當然對索引"視而不見",認為該索引的選擇性不高。
但我們考慮另一種情況,如果一百萬數(shù)據(jù)行實際不是在4種deptno值間
關鍵詞標簽:Oracle索引
相關閱讀
熱門文章 Oracle中使用alter table來增加,刪除,修改列的語法 oracle中使用SQL語句修改字段類型-oracle修改SQL語句案例 誤刪Oracle數(shù)據(jù)庫實例的控制文件 為UNIX服務器設置Oracle全文檢索
人氣排行 oracle中使用SQL語句修改字段類型-oracle修改SQL語句案例 Oracle中使用alter table來增加,刪除,修改列的語法 ORACLE SQL 判斷字符串是否為數(shù)字的語句 ORACLE和SQL語法區(qū)別歸納(1) oracle grant 授權語句 ORACLE修改IP地址后如何能夠使用 如何加速Oracle大批量數(shù)據(jù)處理 Oracle刪除表的幾種方法