Oracle 索引 詳解

一. 索引介紹

 1.1  索引的創建 語法   

CREATE UNIUQE | BITMAP INDEX <schema>.<index_name>

       ON <schema>.<table_name>

            (<column_name> | <expression> ASC | DESC, 
              <column_name> | <expression> ASC | DESC,...) 
     TABLESPACE <tablespace_name> 
     STORAGE <storage_settings> 
     LOGGING | NOLOGGING 
    COMPUTE STATISTICS 
     NOCOMPRESS | COMPRESS<nn> 
     NOSORT | REVERSE 
     PARTITION | GLOBAL PARTITION<partition_setting>

 

相關說明

1)  UNIQUE | BITMAP :指定UNIQUE 爲唯一值索引, BITMAP 爲位圖索引, 省略爲B-Tree 索引。 
2) <column_name> | <expression> ASC | DESC :可以對多列進行聯合索引,當爲expression 時即 “ 基於函數的索引 ” 
3) TABLESPACE :指定存放索引的表空間 (索引和原表不在一個表空間時效率更高 ) 
4) STORAGE :可進一步設置表空間的存儲參數 
5) LOGGING | NOLOGGING :是否對索引產生重做日誌( 對大表儘量使用 NOLOGGING 來減少佔用空間並提高效率 ) 
6) COMPUTE STATISTICS :創建新索引時收集統計信息 
7) NOCOMPRESS | COMPRESS<nn> :是否使用“ 鍵壓縮 ”( 使用鍵壓縮可以刪除一個鍵列中出現的重複值 ) 
8) NOSORT | REVERSE :NOSORT 表示與表中相同的順序創建索引, REVERSE 表示相反順序存儲索引值 
9) PARTITION | NOPARTITION :可以在 分區表 和未分區表上對創建的索引進行分區

 

 

1. 2  索引特點:  

第一 ,通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。 

第二 ,可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。 

第三 ,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。 

第四 ,在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。 

第五 ,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。 

 

 

1. 3  索引不足:

第一 ,創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加。 

第二 ,索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。 

第三 ,當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。 

 

 

1. 4  應該建索引列的特點:

1) 在經常需要搜索的列上,可以加快搜索的速度; 

2) 在作爲主鍵的列上,強制該列的唯一性和組織表中數據的排列結構; 

3) 在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度; 

4) 在經常需要根據範圍進行搜索的列上創建索引,因爲索引已經排序,其指定的範圍是連續的; 

5) 在經常需要排序的列上創建索引,因爲索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間; 

6) 在經常使用在WHERE 子句中的列上面創建索引,加快條件的判斷速度。 

 

 

1. 5  不應該建索引列的特點:

第一 ,對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因爲,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。 

第二 ,對於那些只有很少數據值的列也不應該增加索引。這是因爲,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。 

第三 ,對於那些定義爲 blob 數據類型的列不應該增加索引。這是因爲,這些列的數據量要麼相當大,要麼取值很少。 

第四 ,當修改性能遠遠大於檢索性能時,不應該創建索引。這是因爲,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。 

 

 

1.6  限制索引 
限制索引是一些沒有經驗的開發人員經常犯的錯誤之一。在SQL 中有很多陷阱會使一些索引無法使用。下面討論一些常見的問題: 
     1.6.1   使用不等於操作符(<> 、 != )        
     下面的查詢即使在cust_rating 列有一個索引,查詢語句仍然執行一次全表掃描。       
   select cust_Id,cust_name from customers where  cust_rating <> 'aa';         
把上面的語句改成如下的查詢語句,這樣,在採用基於規則的優化器而不是基於代價的優化器(更智能)時,將會使用索引。         
  select cust_Id,cust_name from customers where cust_rating < 'aa' or cust_rating > 'aa'; 
  特別注意:通過把不等於操作符改成 OR 條件,就可以使用索引,以避免全表掃描。 
     1.6. 2 使用 IS NULL  或 IS NOT NULL 
   使用 IS NULL  或 IS NOT NULL 同樣會限制索引的使用 。因爲 NULL 值並沒有被定義。在 SQL 語句中使用NULL 會有很多的麻煩。因此建議開發人員在建表時,把需要索引的列設成  NOT NULL 。如果被索引的列在某些行中存在 NULL 值,就不會使用這個索引(除非索引是一個位圖索引,關於位圖索引在稍後在詳細討論)。 
    1.6 .3 使用函數 
   如果不使用基於函數的索引,那麼在SQL 語句的 WHERE 子句中對存在索引的列使用函數時,會使優化器忽略掉這些索引。 

  下面的查詢不會使用索引(只要它不是基於函數的索引) 
 select empno,ename,deptno from emp  where  trunc(hiredate)='01-MAY-81'; 
   把上面的語句改成下面的語句,這樣就可以通過索引進行查找。 
select empno,ename,deptno from emp where  hiredate<(to_date('01-MAY-81')+0.9999);

   1.6 .4 比較不匹配的數據類型        
也是比較難於發現的性能問題之一。 注意下面查詢的例子,account_number 是一個 VARCHAR2 類型 , 在account_number 字段上有索引。

下面的語句將執行全表掃描 

  select bank_name,address,city,state,zip from banks where account_number = 990354; 
  Oracle可以自動把 where 子句變成 to_number(account_number)=990354 ,這樣就限制了索引 的使用 , 改成下面的查詢就可以使用索引: 
 select bank_name,address,city,state,zip from banks where account_number ='990354';

特別注意: 不匹配的數據類型之間比較會讓Oracle 自動限制索引的使用 , 即便對這個查詢執行 Explain Plan也不能讓您明白爲什麼做了一次 “ 全表掃描 ” 。

 

 

1. 7  查詢 索引 
查詢DBA_INDEXES 視圖可得到表中所有索引的列表,注意只能通過 USER_INDEXES 的方法來檢索模式(schema) 的索引。訪問 USER_IND_COLUMNS 視圖可得到一個給定表中被索引的特定列。


1. 8   組合索引 
當某個索引包含有多個已索引的列時,稱這個索引爲 組合(concatented )索引 。在 Oracle9i 引入跳躍式掃描的索引訪問方法之前,查詢只能在有限條件下使用該索引。比如:表 emp 有一個組合索引鍵,該索引包含了 empno、  ename 和 deptno 。在 Oracle9i 之前除非在 where 之句中對第一列( empno )指定一個值,否則就不能使用這個索引鍵進行一次範圍掃描。 
    特別注意:在Oracle9i 之前,只有在使用到索引的前導索引時纔可以使用組合索引! 
 

1. 9  ORACLE ROWID 
通過每個行的ROWID ,索引 Oracle 提供了訪問單行數據的能力。 ROWID 其實就是直接指向單獨行的線路圖。如果想檢查重複值或是其他對 ROWID 本身的引用,可以在任何表中使用和指定 rowid 列。

 

1.10  選擇性 
   使用USER_INDEXES 視圖,該視圖中顯示了一個 distinct_keys 列。比較一下唯一鍵的數量和表中的行數,就可以判斷索引的選擇性。選擇性越高,索引返回的數據就越少。


1.11  羣集因子(Clustering Factor) 
  Clustering Factor位於 USER_INDEXES 視圖中。該列反映了數據相對於已  索引的列是否顯得有序。如果Clustering Factor 列的值接近於索引中的樹葉塊 (leaf block) 的數目,表中的數據就越有序。如果它的值接近於表中的行數,則表中的數據就不是很有序。


1.12  二元高度(Binary height) 
  索引的二元高度對把ROWID 返回給用戶進程時所要求的 I/O 量起到關鍵作用。在對一個索引進行分析後,可以通過查詢 DBA_INDEXES 的 B- level 列查看它的二元高度 。二元高度主要隨着表的大小以及被索引的列中值的範圍的狹窄程度而變化。索引上如果有大量被刪除的行,它的二元高度也會增加。更新索引列也類似於刪除操作,因爲它增加了已刪除鍵的數目。 重建索引可能會降低二元高度 


1.13  快速全局掃描 
    Oracle7.3後就可以使用快速全局掃描 (Fast Full Scan) 這個選項。這個選項允許 Oracle 執行一個全局索引掃描操作。快速全局掃描讀取 B- 樹索引上所有樹葉塊。初始化文件中的  DB_FILE_MULTIBLOCK_READ_COUNT參數可以控制同時被讀取的塊的數目。


1.14  跳躍式掃描 
  從Oracle9i 開始,索引跳躍式掃描特性可以允許優化器使用組合索引,即便索引的前導列沒有出現在 WHERE 子句中。索引跳躍式掃描比全索引掃描 要快的多。


下面的 比較他們的區別  
SQL> set timing on

SQL> create index TT_index on TT(teamid,areacode);

索引已創建。

已用時間:  00: 02: 03.93

SQL> select count(areacode) from tt;

COUNT(AREACODE)

---------------

 7230369

已用時間:  00: 00: 08.31

SQL> select  /*+ index(tt TT_index )*/  count(areacode) from tt;

COUNT(AREACODE)

---------------

7230369

已用時間:  00: 00: 07.37


1.15  索引的類型 

  • B-樹索引     
  • 位圖索引   
  • HASH索引    
  • 索引編排表  
  • 反轉鍵索引
  • 基於函數的索引
  • 分區索引
  • 本地和全局索引

 

 

 

 

 

二. 索引分類

Oracle提供了大量索引選項。知道在給定條件下使用哪個選項對於一個應用程序的性能來說非常重要。一個錯誤的選擇可能會引發死鎖,並導致數據庫性能急劇下降或進程終止。而如果做出正確的選擇,則可以合理使用資源,使那些已經運行了幾個小時甚至幾天的進程在幾分鐘得以完成,這樣會使您立刻成爲一位英雄。 下面 就將簡單的討論每個索引選項。 

下面討論的索引類型: 
B樹索引 (默認類型 ) 
位圖索引 
HASH索引 
索引組織表索引 
反轉鍵(reverse key) 索引 
基於函數的索引 
分區索引( 本地和全局索引 ) 
位圖連接索引 


2.1  B樹索引   (默認類型 ) 
  B樹索引在 Oracle 中是一個通用索引。在創建索引時它就是默認的索引類型 。 B 樹索引可以是一個列的 ( 簡單) 索引,也可以是組合 / 複合 ( 多個列 ) 的索引。 B 樹索引最多可以包括 32  。 
 下圖 的例子中,B 樹索引位於僱員表的 last_name 列上。這個索引的二元高度爲 3 ;接下來, Oracle 會穿過兩個樹枝塊 (branch block) ,到達包含有 ROWID 的樹葉塊。在每個樹枝塊中,樹枝行包含鏈中下一個塊的 ID號。 
樹葉塊包含  索引值  ROWID ,以及指向前一個和後一個樹葉塊的 指針 。Oracle 可以從兩個方向遍歷這個二叉樹。 B 樹索引保存了在索引列上有值的每個數據行的 ROWID 值。 Oracle不會對索引列上包含 NULL 值的行進行索引 。如果索引是多個列的組合索引,而其中列上包含NULL 值,這一行就會處於包含 NULL 值的索引列中,且將被處理爲空 ( 視爲 NULL) 。 
                          

技巧  索引列的值都存儲在索引中。因此,可以建立一個組合 ( 複合 ) 索引,這些索引可以直接滿足查詢,而不用訪問表。這就不用從表中檢索數據,從而減少了 I/O 量。


B-tree  特點  

  1. 適合與大量的增、刪、改(OLTP )
  2.  不能用包含OR 操作符的查詢;
  3.  適合高基數的列(唯一值多)
  4.  典型的樹狀結構;
  5.  每個結點都是數據塊;
  6.  大多都是物理上一層、兩層或三層不定,邏輯上三層;
  7.  葉子塊數據是排序的,從左向右遞增;
  8.  在分支塊和根塊中放的是索引的範圍;

 


2.2  位圖索引 
位圖索引非常適合於決策支持系統(Decision Support System , DSS) 和數據倉庫 ,它們不應該用於通過事務處理應用程序訪問的表。它們可以使用較少到中等基數( 不同值的數量 ) 的列訪問非常大的表。儘管位圖索引最多可達 30 個列,但通常它們都只用於少量的列。 
例如,您的表可能包含一個稱爲Sex 的列,它有兩個可能值:男和女。這個基數只爲 2 ,如果用戶頻繁地根據 Sex列的值查詢該表,這就是位圖索引的基列。當一個表內包含了多個位圖索引時,您可以體會到位圖索引的真正威力。如果有多個可用的位圖索引, Oracle 就可以合併從每個位圖索引得到的結果集,快速刪除不必要的數據。


Bitmap t 特點  

  1. 適合與決策支持系統;
  2.  做UPDATE 代價非常高;
  3.  非常適合OR 操作符的查詢;
  4.  基數比較少的時候才能建位圖索引;


技巧: 對於有較低基數的列需要使用位圖索引。性別列就是這樣一個例子,它有兩個可能值:男或女( 基數僅爲2) 。 位圖對於低基數( 少量的不同值 ) 列來說非常快 ,這是因爲索引的尺寸相對於B 樹索引來說小了很多。因爲這些索引是低基數的 B 樹索引,所以非常小,因此您可以經常檢索表中超過半數的行,並且仍使用位圖索引。 
當大多數條目不會向位圖添加新的值時,位圖索引在批處理( 單用戶 ) 操作中加載表 ( 插入操作 ) 方面通常要比 B樹做得好。當多個會話同時向表中插入行時不應該使用位圖索引,在大多數事務處理應用程序中都會發生這種情況。 

示例 
下面來看一個示例表PARTICIPANT ,該表包含了來自個人的調查數據。列 Age_Code 、 Income_Level 、Education_Level 和 Marital_Status 都包括了各自的位圖索引。 下圖 顯示了每個直方圖中的數據平衡情況,以及對訪問每個位圖索引的查詢的執行路徑。圖中的執行路徑顯示了有多少個位圖索引被合併,可以看出性能得到了顯著的提高。 

B


 上圖 圖所示,優化器依次使用4 個單獨的位圖索引,這些索引的列在 WHERE 子句中被引用。每個位圖記錄指針 ( 例如 0 或 1) ,用於指示表中的哪些行包含位圖中的已知值。有了這些信息後, Oracle 就執行 BITMAP AND操作以查找將從所有 4 個位圖中返回哪些行。該值然後被轉換爲 ROWID 值,並且查詢繼續完成剩餘的處理工作。 注意,所有4 個列都有非常低的基數,使用索引可以非常快速地返回匹配的行。 

技巧: 在一個查詢中合併多個位圖索引後,可以使性能顯著提高。位圖索引使用固定長度的數據類型要比可變長度的數據類型好。較大尺寸的塊也會提高對位圖索引的存儲和讀取性能。 

下面的查詢可顯示索引類型。 
SQL> select index_name, index_type from user_indexes;

INDEX_NAME         INDEX_TYPE

------------------------------ ----------------------

TT_INDEX            NORMAL

IX_CUSTADDR_TP    NORMAL

B樹索引 作爲NORMAL 列出;而 位圖索引 的類型值爲 BITMAP  

技巧: 如果要查詢位圖索引列表,可以在USER _INDEXES 視圖中查詢 index_type 列。 
建議不要在一些聯機事務處理(OLTP) 應用程序中使用位圖索引 。B 樹索引的索引值中包含 ROWID ,這樣Oracle 就可以在行級別上鎖定索引。位圖索引存儲爲壓縮的索引值,其中包含了一定範圍的 ROWID ,因此Oracle 必須針對一個給定值鎖定所有範圍內的 ROWID 。這種鎖定類型可能在某些 DML 語句中造成死鎖。SELECT 語句不會受到這種鎖定問題的影響。 
位圖索引 的使用 限制 

  1. 基於規則的優化器不會考慮位圖索引。
  2. 當執行ALTER TABLE 語句並修改包含有位圖索引的列時,會使位圖索引失效。
  3.  位圖索引不包含任何列數據,並且不能用於任何類型的完整性檢查。
  4.  位圖索引不能被聲明爲唯一索引。
  5.  位圖索引的最大長度爲30 。


技巧: 不要在繁重的OLTP 環境中使用位圖索引 

2.3  HASH索引 
使用HASH 索引必須要使用 HASH 集羣 。建立一個集羣或HASH 集羣的同時,也就定義了一個集羣鍵。這個鍵告訴 Oracle 如何在集羣上存儲表。在存儲數據時,所有與這個集羣鍵相關的行都被存儲在一個數據庫塊上。如果數據都存儲在同一個數據庫塊上,並且將 HASH 索引作爲 WHERE 子句中的確切匹配, Oracle 就可以通過執行一個HASH 函數和 I/O 來訪問數據 —— 而通過使用一個二元高度爲 4 的 B 樹索引來訪問數據,則需要在檢索數據時使用 4 個 I/O 。如 下圖 所示,其中的查詢是一個等價查詢,用於匹配HASH 列和確切的值。 Oracle 可以快速使用該值,基於 HASH 函數確定行的物理存儲位置。 
HASH索引可能是訪問數據庫中數據的最快方法,但它也有自身的缺點 。集羣鍵上不同值的數目必須在創建HASH集羣之前就要知道。需要在創建 HASH 集羣的時候指定這個值。低估了集羣鍵的不同值的數字可能會造成集羣的衝突 ( 兩個集羣的鍵值擁有相同的 HASH 值 ) 。這種衝突是非常消耗資源的。衝突會造成用來存儲額外行的緩衝溢出,然後造成額外的 I/O 。如果不同 HASH 值的數目已經被低估,您就必須在重建這個集羣之後改變這個值。

ALTER CLUSTER命令不能改變 HASH 鍵的數目。 HASH 集羣還可能浪費空間 。如果無法確定需要多少空間來維護某個集羣鍵上的所有行,就可能造成空間的浪費。如果 不能爲集羣的未來增長分配好附加的空間 ,HASH集羣可能就 不是最好的選擇  如果應用程序經常在集羣表上進行全表掃描 ,HASH 集羣可能也 不是最好的選擇。由於需要爲未來的增長分配好集羣的剩餘空間量,全表掃描可能非常消耗資源。 
在實現HASH 集羣之前一定要小心。您需要全面地觀察應用程序,保證在實現這個選項之前已經瞭解關於表和數據的大量信息。 通常,HASH 對於一些包含有序值的靜態數據非常有效。 

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

2.4  索引組織表 
索引組織表會把表的存儲結構改成B 樹結構,以表的主鍵進行排序。這種特殊的表和其他類型的表一樣,可以在表上執行所有的 DML 和 DDL 語句。 由於表的特殊結構,ROWID 並沒有被關聯到表的行上。 
對於一些涉及精確匹配和範圍搜索的語句,索引組織表提供了一種基於鍵的快速數據訪問機制。 基於主鍵值的UPDATE 和 DELETE 語句的性能也同樣得以提高, 這是因爲行在物理上有序。由於鍵列的值在表和索引中都沒有重複, 存儲所需要的空間也隨之減少。 
如果不會頻繁地根據主鍵列查詢數據,則需要在索引組織表中的其他列上創建二級索引。不會頻繁根據主鍵查詢表的應用程序不會瞭解到使用索引組織表的全部優點。 對於總是通過對主鍵的精確匹配或範圍掃描進行訪問的表,就需要考慮使用索引組織表。 

技巧: 可以在索引組織表上建立二級索引。 

2.5  反轉鍵索引 
當載入一些有序數據時,索引肯定會碰到與I/O 相關的一些瓶頸。在數據載入期間,某部分索引和磁盤肯定會比其他部分使用頻繁得多。爲了解決這個問題,可以把索引表空間存放在能夠把 文件物理分割在多個磁盤上的磁盤體系結構上  
爲了解決這個問題,Oracle 還提供了一種反轉鍵索引的方法。如果數據以反轉鍵索引存儲,這些數據的值就會與原先存儲的數值相反。這樣,數據 1234 、 1235 和 1236 就被存儲成 4321 、 5321 和 6321 。 結果就是索引會爲每次新插入的行更新不同的索引塊。 

技巧: 如果您的磁盤容量有限,同時還要執行大量的有序載入,就可以使用反轉鍵索引。 
不可以將反轉鍵索引與位圖索引或索引組織表結合使用。 因爲 不能對位圖索引和索引組織表進行反轉鍵處理。 


2.6  基於函數的索引 
可以在表中創建基於函數的索引。如果沒有基於函數的索引,任何在列上執行了函數的查詢都不能使用這個列的索引。例如,下面的查詢就不能使用JOB 列上的索引,除非它是基於函數的索引: 
select *   from emp   where UPPER(job) = 'MGR'; 
下面的查詢使用JOB 列上的索引,但是它將不會返回 JOB 列具有 Mgr 或 mgr 值的行: 
select *   from emp   where job = 'MGR';


可以創建這樣的索引,允許索引訪問支持基於函數的列或數據。可以對列表達式UPPER(job) 創建索引,而不是直接在 JOB 列上建立索引 ,如  
create index EMP$UPPER_JOB on   emp(UPPER(job));


儘管基於函數的索引非常有用,但在建立它們之前必須先考慮下面一些問題: 
能限制在這個列上使用的函數嗎?如果能,能限制所有在這個列上執行的所有函數嗎 
是否有足夠應付額外索引的存儲空間? 
在每列上增加的索引數量會對針對該表執行的DML 語句的性能帶來何種影響? 

基於函數的索引非常有用,但在實現時必須小心。在表上創建的索引越多,INSERT 、 UPDATE 和 DELETE語句的執行就會花費越多的時間。 

注意: 對於優化器所使用的基於函數的索引來說, 必須把初始參數QUERY _REWRITE _ ENABLED 設定爲TRUE 。 

示例: 
select    count(*)   from    sample   where ratio(balance,limit) >.5; 
Elapsed time: 20.1 minutes


create index ratio_idx1 on   sample (ratio(balance, limit));


select  count(*)   from  sample   where ratio(balance,limit) >.5; 
Elapsed time: 7 seconds!!! 

2.7  分區索引 
分區索引就是簡單地把一個索引分成多個片斷。通過把一個索引分成多個片斷,可以訪問更小的片斷( 也更快 ) ,並且可以把這些片斷分別存放在不同的磁盤驅動器上 ( 避免 I/O 問題 ) 。 B樹和位圖索引都可以被分區,而 HASH索引不可以被分區 。可以有好幾種分區方法: 表被分區而索引未被分區  表未被分區而索引被分區  表和索引都被分區 。不管採用哪種方法, 都必須使用基於成本的優化器 。分區能夠提供更多可以提高性能和可維護性的可能性 
有兩種類型的分區索引: 本地分區索引  全局分區索引 。每個類型都有兩個子類型,有前綴索引和無前綴索引。表各列上的索引可以有各種類型索引的組合。 如果使用了位圖索引,就必須是本地索引 。把索引分區最主要的原因是可以減少所需讀取的索引的大小,另外把分區放在不同的表空間中可以提高分區的可用性和可靠性。 
在使用分區後的表和索引時,Oracle 還支持並行查詢和並行 DML 。這樣就可以同時執行多個進程,從而加快處理這條語句。 
2.7. 1.本地分區索引 ( 通常使用的索引 ) 
可以使用與表相同的分區鍵和範圍界限來對本地索引分區。每個本地索引的分區只包含了它所關聯的表分區的鍵和ROWID 。本地索引可以是 B 樹或位圖索引。如果是 B 樹索引,它可以是唯一或不唯一的索引。 
這種類型的索引支持分區獨立性,這就意味着對於單獨的分區,可以進行增加、截取、刪除、分割、脫機等處理,而不用同時刪除或重建索引。 Oracle自動維護這些本地索引。 本地索引分區還可以被單獨重建,而其他分區不會受到影響。


2.7.1.1  有前綴的索引 
有前綴的索引包含了來自分區鍵的鍵,並把它們作爲索引的前導。例如,讓我們再次回顧participant 表。在創建該表後,使用 survey_id 和 survey_date 這兩個列進行範圍分區,然後在 survey_id 列上建立一個有前綴的本地索引,如 下圖 所示。這個索引的所有分區都被等價劃分,就是說索引的分區都使用表的相同範圍界限來創建。 
                 


技巧: 本地的有前綴索引可以讓Oracle 快速剔除一些不必要的分區。也就是說沒有包含 WHERE 條件子句中任何值的分區將不會被訪問,這樣也提高了語句的性能。 

2.7.1.2  無前綴的索引 
無前綴的索引並沒有把分區鍵的前導列作爲索引的前導列。若使用有同樣分區鍵(survey_id 和 survey_date) 的相同分區表,建立在 survey_date 列上的索引就是一個本地的無前綴索引,如 下圖 所示。可以在表的任一列上創建本地無前綴索引,但索引的每個分區只包含表的相應分區的鍵值。 
                          

 


如果要把無前綴的索引設爲唯一索引,這個索引就必須包含分區鍵的子集。在這個例子中,我們必須把包含survey和 ( 或 )survey_id 的列進行組合 ( 只要 survey_id 不是索引的第一列,它就是一個有前綴的索引 ) 。 

技巧: 對於一個唯一的無前綴索引,它必須包含分區鍵的子集。 

2.7. 2.   全局分區索引 
全局分區索引在一個索引分區中包含來自多個表分區的鍵。一個全局分區索引的分區鍵是分區表中不同的或指定一個範圍的值。在創建全局分區索引時,必須定義分區鍵的範圍和值。 全局索引只能是B 樹索引  Oracle在默認情況下不會維護全局分區索引。如果一個分區被截取、增加、分割、刪除等,就必須重建全局分區索引 ,除非在修改表時指定ALTER TABLE 命令的 UPDATE GLOBAL INDEXES 子句。


2.7.2.1  有前綴的索引 
通常,全局有前綴索引在底層表中沒有經過對等分區。沒有什麼因素能限制索引的對等分區,但Oracle 在生成查詢計劃或執行分區維護操作時,並不會充分利用對等分區。如果索引被對等分區,就必須把它創建爲一個本地索引,這樣 Oracle 可以維護這個索引,並使用它來刪除不必要的分區,如 下圖 所示。在該圖的3 個索引分區中,每個分區都包含指向多個表分區中行的索引條目。 
         
                        


          分區的、全局有前綴索引 

技巧  如果一個全局索引將被對等分區,就必須把它創建爲一個本地索引,這樣Oracle 可以維護這個索引,並使用它來刪除不必要的分區。


2.7.2.2  無前綴的索引 
Oracle不支持無前綴的全局索引。 

2.8  位圖連接索引 
位圖連接索引是基於兩個表的連接的位圖索引,在數據倉庫環境中使用這種索引改進連接維度表和事實表的查詢的性能。創建位圖連接索引時,標準方法是連接索引中常用的維度表和事實表。當用戶在一次查詢中結合查詢事實表和維度表時,就不需要執行連接,因爲在位圖連接索引中已經有可用的連接結果。通過壓縮位圖連接索引中的ROWID 進一步改進性能,並且減少訪問數據所需的 I/O 數量。


創建位圖連接索引時,指定涉及的兩個表。相應的語法應該遵循如下模式: 
create bitmap index FACT_DIM_COL_IDX   on FACT(DIM.Descr_Col)   from FACT, DIM 
where FACT.JoinCol = DIM.JoinCol;


位圖連接的語法比較特別,其中包含FROM 子句和 WHERE 子句,並且引用兩個單獨的表。索引列通常是維度表中的描述列 —— 就是說,如果維度是 CUSTOMER ,並且它的主鍵是 CUSTOMER_ID ,則通常索引Customer_Name 這樣的列。如果事實表名爲 SALES ,可以使用如下的命令創建索引: 
create   bitmap   index   SALES_CUST_NAME_IDX

on  SALES(CUSTOMER.Customer_Name)    from SALES, CUSTOMER 
where  SALES.Customer_ID=CUSTOMER.Customer_ID;


如果用戶接下來使用指定Customer_Name 列值的 WHERE 子句查詢 SALES 和 CUSTOMER 表,優化器就可以使用位圖連接索引快速返回匹配連接條件和 Customer_Name 條件的行。


位圖連接索引的使用一般會受到限制 

1) 只可以索引維度表中的列。

2) 用於連接的列必須是維度表中的主鍵或唯一約束;如果是複合主鍵,則必須使用連接中的每一列。

3) 不可以對索引組織表創建位圖連接索引,並且適用於常規位圖索引的限制也適用於位圖連接索引。

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