1. 程式人生 > >oracle的sql優化-oracle的索引介紹原理淺析(B-Tree索引)

oracle的sql優化-oracle的索引介紹原理淺析(B-Tree索引)

B 樹索引(B-Tree索引

B樹索引是我們在oracle資料庫中最常用的索引,在詳細介紹訪問方法之前,我們看一下B-TREE索引的結構(圖片來源網路)

         oracle的B樹索引就好像一顆長到的樹,他包含兩種型別,一種是索引分支塊(根節點塊,分支節點塊)一種是索引葉子塊(葉子節點塊)。分節點用來搜尋,葉子節點用來儲存資料。根節點儲存索引的低層分支節點的資料。 由於所有的葉子節點均會自動的儲存成相同的深度,所以稱為“平衡樹索引”, 故此,從任何葉子處檢索資料消耗的時間都是相同的
       對於分支節點塊(包括根節點塊)來說,其所包含的索引條目都是按照順序排列的(預設是升序排列,也可以在建立索引時指定為降序排列)。每個索引條目(也可以叫做每條記錄)都具有兩個欄位。第一個欄位表示當前該分支節點塊下面所連結的索引塊中所包含的最小鍵值;第二個欄位為四個位元組,表示所連結的索引塊的地址,該地址指向下面一個索引塊。 比如從上圖一可以看到,對於根節點塊來說,包含三條記錄,分別為(0 B1)、(500 B2)、(1000 B3),它們指向三個分支節點塊。其中的0、500和1000分別表示這三個分支節點塊所連結的鍵值的最小值。而B1、B2和B3則表示所指向的三個分支節點塊的地址。
在一個分支節點塊中所能容納的記錄 行數由資料塊大小以及索引鍵值的長度決定
       對於葉子節點塊來說,其所包含的索引條目與分支節點一樣,都是按照順序排列的(預設是升序排列,也可以在建立索引時指定為降序排列)。每個索引條目(也可以叫做每條記錄)也具有兩個欄位。第一個欄位表示索引的鍵值,對於單列索引來說是一個值;而對於多列索引來說則是多個值組合在一起的。第二個欄位表示鍵值所對應的記錄行的ROWID,該ROWID是記錄行在表裡的實體地址。
       當用戶建立索引時,Oracle 取得所有被索引列的資料並進行排序,之後將排序後索引值和與此值相對應的 rowid 按照從下到上的順序載入到索引中。例如,以下語句:
CREATE INDEX employees_last_name ON employees(last_name); 
       Oracle 先將 employees 表按 last_name 列排序,再將排序後的 列及相應的 rowid 按從下到上的順序載入到索引中。使用此索引時,Oracle 可以快速地搜尋已排序的 last_name 值,並使用相應的 rowid 去定位包含使用者所查詢的 last_name 值的資料行。
在一個平衡樹索引中,最底層的索引塊(葉塊)儲存了被索引的資料值,以及對應的 rowid。葉塊之間以雙向連結串列的形式相互連線。位於葉塊之上分支塊中包含了
指向下層索引塊的指標。
 接下來介紹一個索引查詢的流程,從上往下,第一層為根節點,第二層為分支節點,第三層為葉子節點(包含了列值和rowid)。比如我們的條件為where=29,(補充說明如果被索引的列儲存的是字元資料,那麼索引值為這些字元資料在當前資料庫字符集中的二進位制值)就從跟節點開始查詢,29在0-500中,指向分支節點最左邊第一個分支節點塊(也就是B1),就B1中去找,發現29在0-200中,指向葉子節點的L1,於是在L1中找到29的值和響應的rowid。如果只查詢索引列的值,就不用根據rowid去表中查找了,如果還要查詢值29這行的其他列的值就得根據rowid去表裡查查詢(這個過程叫做回表查詢)。葉子節點還有個雙向連結串列(如圖)。在通過索引進行範圍掃描時會起作用,比如要查詢值29-700,如果當查詢到值29的時候,不就會再從跟節點開始查詢其他的值,而是根據本葉子節點連結串列的指向去查詢其他的值。
參考文章http://blog.csdn.net/zhifeiyu2008/article/details/8309889