優化Oracle庫表設計的若干方法(三)

2、顯式爲主鍵列建立反向鍵索引

  2.1 反向鍵索引的原理和用途

  我們知道Oracle會自動爲表的主鍵列建立索引,這個默認的索引是普通的B-Tree索引。對於主鍵值是按順序(遞增或遞減)加入的情況,默認的B-Tree索引並不理想。這是因爲如果索引列的值具有嚴格順序時,隨着數據行的插入,索引樹的層級增長很快。搜索索引發生的I/O讀寫次數和索引樹的層級數成正比,也就是說,一棵具有5個層級的B-Tree索引,在最終讀取到索引數據時最多可能發生多達5次I/O操作。因而,減少索引的層級數是索引性能調整的一個重要方法。

  如果索引列的數據以嚴格的有序的方式插入,那麼B-Tree索引樹將變成一棵不對稱的"歪樹",如圖 5所示:


圖 5不對稱的B-Tree索引

  而如果索引列的數據以隨機值的方式插入,我們將得到一棵趨向對稱的索引樹,如圖 6所示:


圖 6對稱的B-Tree索引

  比較圖 5和圖 6,在圖 5中搜索到A塊需要進行5次I/O操作,而圖 6僅需要3次I/O操作。

  既然索引列數據從序列中獲取,其有序性無法規避,但在建立索引時,Oracle允許對索引列的值進行反向,即預先對列值進行比特位的反向,如1000,10001,10011,10111,1100經過反向後的值將是0001,1001,1101,0011。顯然經過位反向處理的有序數據變得比較隨機了,這樣所得到的索引樹就比較對稱,從而提高表的查詢性能。

  但反向鍵索引也有它侷限性:如果在WHERE語句中,需要對索引列的值進行範圍性的搜索,如BETWEEN、<、>等,其反向鍵索引無法使用,此時,Oracle將執行全表掃描;只有對反向鍵索引列進行 <> 和 = 的比較操作時,其反向鍵索引纔會得到使用。

  2.2 反向鍵索引的SQL語句

  回到我們上面的例子,由於T_ORDER和T_ORDER_ITEM的主鍵值來源於序列,主鍵值是有嚴格順序的,所以我們應該摒棄默認的Oracle所提供的索引,而採取顯式爲主鍵指定一個反向鍵索引的方式。

  ORDER_ID爲T_ORDER表的主鍵,主鍵名爲PK_ORDER,我們爲ORDER_ID列上建立一個反向鍵索引IDX_ORDER_ID,並使PK_ORDER_ID使用這個索引,其SQL語句如下:

create table T_ORDER (
 ORDER_ID NUMBER(10) not null,
 CLIENT VARCHAR2(60),
 ADDRESS VARCHAR2(100),
 ORDER_DATE CHAR(8));
create unique index IDX_ORDER_ID on T_ORDER ( ORDER_ID ASC) reverse;alter table T_ORDER add constraint PK_ORDER primary key (ORDER_ID) using index IDX_ORDER_ID;

  要保證創建IDX_ORDER_ID的SQL語句在創建PK_ORDER主鍵的SQL語句之前,因爲主鍵需要引用到這個反向鍵索引。

  由於主鍵列的數據是唯一的,所以爲IDX_ORDER_ID加上unique限定,使其成爲唯一型的索引。


create table T_ORDER (…);alter table T_ORDER add constraint PK_T_ORDER primary key (ORDER_ID) using index IDX_ORDER_ID;create unique index IDX_ORDER_ID on T_ORDER ( ORDER_ID ASC) reverse;

  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章