oracle索引原理(b-tree,bitmap,聚集,非叢集索引)__oracle

來源:互聯網
上載者:User

一個B樹索引只有一個根節點,它實際就是位於樹的最頂端的分支節點。

可以用下圖一來描述B樹索引的結構。其中,B表示分支節點,而L表示葉子節點。



    對於分支節點塊(包括根節點塊)來說,其所包含的索引條目都是按照順序排列的(預設是升序排列,也可以在建立索引時指定為降序排列)。每個索引條目(也可以叫做每條記錄)都具有兩個欄位。第一個欄位表示當前該分支節點塊下面所連結的索引塊中所包含的最小索引值;第二個欄位為四個位元組,表示所連結的索引塊的地址,該地址指向下面一個索引塊。在一個分支節點塊中所能容納的記錄行數由資料區塊大小以及索引索引值的長度決定。比如從上圖一可以看到,對於根節點塊來說,包含三條記錄,分別為(0 B1)、(500 B2)、(1000 B3),它們指向三個分支節點塊。其中的0、500和1000分別表示這三個分支節點塊所連結的索引值的最小值。而B1、B2和B3則表示所指向的三個分支節點塊的地址。

    對於葉子節點塊來說,其所包含的索引條目與分支節點一樣,都是按照順序排列的(預設是升序排列,也可以在建立索引時指定為降序排列)。每個索引條目(也可以叫做每條記錄)也具有兩個欄位。第一個欄位表示索引的索引值,對於單列索引來說是一個值;而對於多列索引來說則是多個值組合在一起的。第二個欄位表示索引值所對應的記錄行的ROWID,該ROWID是記錄行在表裡的物理地址。如果索引是建立在非分區表上或者索引是分區表上的本地索引的話,則該ROWID佔用6個位元組;如果索引是建立在分區表上的全域索引的話,則該ROWID佔用10個位元組。

  bitmap索引

      位元影像(bitmap)索引是另外一種索引類型,它的組織形式與B樹索引相同,也是一棵平衡樹。與B樹索引的區別在於葉子節點裡存放索引條目的方式不同。從前面我們知道,B樹索引的葉子節點裡,對於表裡的每個資料行,如果被索引列的值不為空白的,則會為該記錄行在葉子節點裡維護一個對應的索引條目。
而位元影像索引則不是這樣,其葉子節點裡存放的索引條目如下圖所示。

    假設某個表T裡所有的記錄在列C1上只具有三個值:01、02和03。在表T的C1列上建立位元影像索引以後,則葉子節點的內容如圖9-14所示。可以看到,位元影像索引只有三個索引條目,也就是每個C1列的值對應一個索引條目。位元影像索引條目上還包含表裡第一條記錄所對應的ROWID以及最後一條記錄所對應的ROWID。索引條目的最後一部分則是由多個bit位所組成的bitmap,每個bit位就對應一條記錄。

       當發出where c1='01'這樣的SQL語句時,oracle會去搜尋01所在的索引條目,然後掃描該索引條目中的bitmap裡所有的bit位。第一個bit位為1,則說明第一條記錄上的C1值為01,於是返回第一條記錄所在的ROWID(根據該索引條目裡記錄的start ROWID加上行號得到該記錄所在的ROWID)。第二個bit位為0,則說明第二條記錄上的C1值不為01,依此類推。另外,如果索引列為空白,也會在位元影像索引裡記錄,也就是將對應的bit位設定為0即可。
       如果索引列上不同值的個數比較少的時候,比如對於性別列(男或女)等,則使用位元影像索引會比較好,因為它對空間的佔用非常少(因為都是用bit位來表示表裡的資料行),從而在掃描索引的時候,掃描的索引塊的個數也比較少。可以試想一下,如果在列的不同值非常多的列上,比如主鍵列上,建立位元影像索引,則產生的索引條目就等於表裡記錄的條數,同時每個索引條目裡的bitmap裡,只有一個1,其它都是0。這樣還不如B樹索引的效率高。
如果被索引的列經常被更新的話,則不適合使用位元影像索引。因為當更新位元影像所在的列時,由於要在不同的索引條目之間修改bit位,比如將第一條記錄從01變為02,則必須將01所在的索引條目的第一個bit位改為0,再將02所在的索引條目的第一個bit位改為1。因此,在更新索引條目的過程中,會鎖定位元影像索引裡多個索引條目。也就是同時只能有一個使用者能夠更新表T,從而降低了並發性。
位元影像索引比較適合用在資料倉儲系統裡,不適合用在OLTP系統裡。

  HASH索引

      使用HASH索引必須要使用HASH叢集。建立一個叢集或HASH叢集的同時,也就定義了一個叢集鍵。這個鍵告訴Oracle如何在叢集上儲存表。在儲存資料時,所有與這個叢集鍵相關的行都被儲存在一個資料庫塊上。如果資料都儲存在同一個資料庫塊上,並且將HASH索引作為WHERE子句中的確切匹配,Oracle就可以通過執行一個HASH函數和I/O來訪問資料-- 而通過使用一個二元高度為4的B樹索引來訪問資料,則需要在檢索資料時使用4個I/O。如圖2-5所示,其中的查詢是一個等價查詢,用於匹配HASH列和確切的值。Oracle可以快速使用該值,基於HASH函數確定行的實體儲存體位置。

      HASH索引可能是訪問資料庫中資料的最快方法,但它也有自身的缺點。叢集鍵上不同值的數目必須在建立HASH叢集之前就要知道。需要在建立HASH叢集的時候指定這個值。低估了叢集鍵的不同值的數字可能會造成叢集的衝突(兩個叢集的索引值擁有相同的HASH值)。這種衝突是非常消耗資源的。衝突會造成用來儲存額外行的緩衝溢出,然後造成額外的I/O。如果不同HASH值的數目已經被低估,您就必須在重建這個叢集之後改變這個值。ALTER CLUSTER命令不能改變HASH鍵的數目。

      HASH叢集還可能浪費空間。如果無法確定需要多少空間來維護某個叢集鍵上的所有行,就可能造成空間的浪費。如果不能為叢集的未來增長分配好附加的空間,HASH叢集可能就不是最好的選擇。

如果應用程式經常在叢集表上進行全表掃描,HASH叢集可能也不是最好的選擇。由於需要為未來的增長分配好叢集的剩餘空間量,全表掃描可能非常消耗資源。

 

在實現HASH叢集之前一定要小心。您需要全面地觀察應用程式,保證在實現這個選項之前已經瞭解關於表和資料的大量資訊。通常,HASH對於一些包含有序值的待用資料非常有效。

技巧:

HASH索引在有限制條件(需要指定一個確定的值而不是一個值範圍)的情況下非常有用。

  聚族索引

      在這裡還是用字典來進行類比,一般來說漢語字典中有幾種索引,如拼音、偏旁、筆畫等。字典本身的組織也是排序的,我記得一般是按照拼音排序的。這裡的拼音就是聚族索引。也就是說聚族索引的組織順序和資料本身的組織順序是一致的 ,這也解釋了資料庫中只能定義一個聚族索引的原因,因為資料本身只能按一種方式進行排序。
      那聚族索引有什麼特別的好處呢,這個好處就是在資料庫中執行尋找一批資料的語句會比較快,因為資料已經按照聚族索引排好序了,很少的io操作就可以將資料從庫中取出。好比你在字典中尋找發音從從a到c的漢字,只需要查到a的開始頁和c的結束頁,中間的所有頁都符合查詢要求,不用再一頁一頁地尋找。

 

  非聚族索引

      非聚族索引就好比字典裡的偏旁、筆畫索引,其 索引組織順序和資料群組織順序不一致 ,因此非聚族索引可以建立多個。當尋找一條資料時,非聚族索引和聚族索引的效率相差不大,但尋找一批資料(n)時,非聚族索引需要的io可能是聚族索引的n倍,因為非聚族索引需要一條一條地進行尋找。

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.