天天看點

索引

索引是資料庫中一種可選的資料結構,她通常與表或簇相關。使用者可以在表的一列或數列上建立索引,以提高在此表上執行 sql 語句的性能。就像本文檔的索引可以幫助讀者快速定位所需資訊一樣,oracle 的索引提供了更為迅速地通路表資料的方式。正确地使用索引能夠顯著的減少磁盤 i/o。

使用者可以為一個表建立多個索引,隻要不同索引使用的列或列的組合(combination of columns)不同即可。例如,下列語句中指定的列組合是有效的:

create index employees_idx1 on employees (last_name, job_id);

create index employees_idx2 on employees (job_id, last_name);

oracle 提供了各種類型的索引,她們能夠互為補充地提升查詢性能:

平衡樹索引(b-tree index)

平衡樹簇索引(b-tree cluster index)

哈希簇索引(hash cluster index)

反向鍵索引(reverse key indexes)

位圖索引(bitmap index)

位圖連接配接索引(bitmap join index)

oracle 還支援函數索引(function-based index),以及針對特定應用程式或程式子產品(cartridge)的域索引(domain index)。

無論索引是否存在都無需對已有的 sql 語句進行修改。索引隻是提供了一種快速通路資料的路徑,是以她隻會影響查詢的執行速度。當給出一個已經被索引的資料值後,就可以通過索引直接地定位到包含此值的所有資料行。

索引在邏輯上和實體上都與其基表(base table)是互相獨立的。使用者可以随時建立(create)或移除(drop)一個索引,而不會影響其基表或基表上的其他索引。當使用者移除一個索引時,所有的應用程式仍然能夠繼續工作,但是資料通路速度有可能會降低。作為一種獨立的資料結構,索引需要占用存儲空間。

當索引被建立後,對其的維護與使用都是 oracle 自動完成的。當索引所依賴的資料發生插入,更新,删除等操作時,oracle 會自動地将這些資料變化反映到相關的索引中,無需使用者的額外操作。

即便索引的基表中插入新的資料,對被索引資料的查詢性能基本上能夠保持穩定不變。但是,如果在一個表上建立了過多的索引,将降低其插入,更新,及删除的性能。因為 oracle 必須同時修改與此表相關的索引資訊。

優化器可以使用已有的索引來建立(build)新的索引。這将加快新索引的建立速度。

索引(index)可以是唯一(unique)的或非唯一(nonunique)的。在一個表上建立唯一索引(unique index)能夠保證此表的索引列(一列或多列)不存在重複值。而非唯一索引(nonunique index)并不對索引列值進行這樣的限制。

oracle 建議使用 create unique index 語句顯式地建立唯一索引(unique index)。通過主鍵(primary key)或唯一限制(unique constraint)來建立唯一索引不能保證建立新的索引,而且用這些方式建立的索引不能保證為唯一索引。

複合索引(composite index)(也被稱為連結索引(concatenated index))是指建立在一個表的多列上的索引。複合索引内的列可以任意排列,她們在資料表中也無需相鄰。

如果一個 select 語句的 where 子句中引用了複合索引(composite index)的全部列(all of the column)或自首列開始且連續的部分列(leading portion of the column),将有助于提高此查詢的性能。是以,索引定義中列的順序是很重要的。大體上說,經常通路的列(most commonly accessed)或選擇性較大的列(most

selective)應該放在前面。

一個正常的(regular)複合索引(composite index)不能超過 32 列,而位圖索引(bitmap index)不能超過 30 列。索引中一個鍵值(key value)的總長度大緻上不應超過一個資料塊(data block)總可用空間的一半。

索引(index)與鍵(key)是連個不同的概念,但是這兩個術語經常被混用。索引是在資料庫中實際存儲的資料結構,使用者可以使用 sql 語句對其進行建立(create),修改(alter),或移除(drop)。索引提供了一種快速通路表資料的途徑。而鍵隻是一個邏輯概念。鍵的概念主要在 oracle 的完整性限制(integrity

constraint)功能中使用,完整性限制用于保證資料庫中的業務規則(business rule)。

因為 oracle 也會使用索引(index)來實作某些完整性限制(integrity constraint),是以索引與鍵(key)這兩個術語經常被混用。注意不要将二者混淆。

對于一個資料表的兩行或多行,如果其索引列(key column)中全部非空(non-null)的值完全相同(identical),那麼在索引中這些行将被認為是相同的;反之,在索引中這些行将被認為是不同的。是以使用unique 索引可以避免将包含 null 的行視為相同的。以上讨論并不包括索引列的列值(column value)全部為null

的情況。

oracle 不會将索引列(key column)全部為

null 的資料行加入到索引中。不過位圖索引(bitmap index)是個例外,簇鍵(cluster key)的列值(column value)全部為null 時也是例外。

如果一個函數(function)或表達式(expression)使用了一個表的一列或多列,則使用者可以依據這些函數或表達式為表建立索引,這樣的索引被稱為函數索引(function-based index)。函數索引能夠計算出函數或表達式的值,并将其儲存在索引中。使用者建立的函數索引既可以是平衡樹類型(b-tree index)的,也可以是位圖類型(bitmap

index)的。

用于建立索引的函數可以是一個數學表達式(arithmetic expression),也可以是使用了 pl/sql 函數(pl/sql function),包函數(package function),c 外部調用(c callout),或 sql 函數(sql function)的表達式。用于建立索引的函數不能包含任何聚合函數(ggregate function),如果為使用者自定義函數,則在聲明中必須使用

deterministic關鍵字。如果在一個使用對象類型(object type)的列上建立函數索引,則可以使用此對象的方法(method)作為函數,例如此對象的 map 方法。使用者不能在資料類型為

lob,ref,或嵌套表(nested table)的列上建立函數索引,也不能在包含lob,ref,或嵌套表等資料類型的對象類型列上建立函數索引。

如果一個 sql 語句的 where 子句中使用了函數,那麼建立相應的函數索引(function-based index)是提高資料通路性能的有效機制。表達式(expression)的結果經過計算後将被存儲在索引中。但是當執行insert 和update 語句時,oracle 需要進行函數運算以便維護索引。

例如,如果使用者建立了以下函數索引:

create index idx on table_1 (a + b * (c – 1), a, b);

當 oracle 處理如下查詢時就可以使用之前建立的索引:

select a from table_1 where a + b * (c – 1) < 100;

使用 upper(column_name) 或

lower(column_name) 函數建立函數索引(function-based index)有助于與大小寫無關(case-insensitive)的查詢。例如建立以下函數索引:

create index uppercase_idx on employees (upper(first_name));

有助于提高以下查詢的性能:

select * from employees where upper(first_name) = ‘richard’;

使用者必須為優化器(optimizer)收集關于函數索引(unction-based index)的統計資訊(statistic)。否則處理 sql 語句時将不會使用此索引。

當一個查詢的 where 子句中含有表達式(expression)時,優化器可以對函數索引(function-based index)進行索引區間掃描(index range scan)。例如以下查詢:

select * from t where a + b < 10;

如果使用表達式(expression) a+b 建立的索引,優化器(optimizer)就能夠進行索引區間掃描(index range scan)。如果謂詞(predicate,即where 子句)産生的選擇性(selectivity)較低,則對區間掃描極為有利。此外,如果表達式的結果物化在函數索引内(function-based index),優化器将能更準确地估計使用此表達式的謂詞的選擇性。

優化器(optimizer)能夠将 sql 語句及函數索引(function-based index)中的表達式解析為表達式樹(expression tree)并進行比較,進而實作表達式比對。這個比較過程是大小寫無關的(case-insensitive),并将忽略所有空格(blank space)。

函數索引(function-based index)依賴于索引定義表達式中使用的函數。如果此函數為 pl/sql 函數(pl/sql function)或包函數(package function),當函數聲明(function specification)發生變化時,索引将失效(disabled)。

使用者需要被授予(grant)create index 或

create any index 權限才能建立函數索引(function-based index)。

要想使用函數索引(function-based index):

建立索引後,表必須經過分析(analyze)。

必須保證查詢的條件表達式不是 null 值, 因為

null 值不會被存儲到索引中。

以下各節将講述使用函數索引的其他需求。

函數索引(function-based index)使用的使用者自定義函數(user-written function)必須聲明為

deterministic,此關鍵字表明對于一定的輸入參數,此函數總會得到相同的輸出結果。

函數索引(function-based index)的所有者(owner)必須具備此索引定義中使用的函數的execute 權限。當 execute 權限被收回(revoke)後,oracle 則将索引辨別為 disabled。索引的所有者無須具備此函數的execute with grant option 權限,即可将索引所在表的select

權限授予(grant)其他使用者。

函數索引(function-based index)依賴于她使用的所有函數。如果函數或函數所在包的聲明(specification)被修改過(或索引所有者對函數的execute 權限被收回),将會出現以下情況:

索引被标記為 disabled。

如果優化器(optimizer)選擇了在标記為 disabled 的索引上執行查詢,那麼此查詢将失敗

使用标記為 disabled 的索引而執行的 dml 操作将失敗,除非此索引同時被标記為unusable 且初始化參數(initialization parameter)skip_unusable_indexes 被設為true。

函數被修改之後,使用者可以使用 alter index … enable 語句将索引重新置為

enable 狀态。

當使用者建立索引時,oracle 會自動地在表空間(tablespace)中建立索引段(index segment)來存儲索引的資料。使用者可以通過以下方式控制索引段的空間配置設定和使用:

設定索引段的存儲參數(storage parameter)來控制如何為此索引段配置設定資料擴充(extent)

為索引段設定 pctfree 參數,來控制組成資料擴充的各個資料塊(data block)的可用空間情況。

索引段(index segment)使用的表空間(tablespace)既可以是索引所有者(owner)的預設表空間,也可以是在

create index 語句中指定的表空間。索引無需和其相關的表位于同一表空間中。相反,如果将索引與其相關表存儲在不同磁盤上能夠提升使用此索引的查詢性能,因為此時 oracle 能夠并行地(parallel)通路索引及表資料。

一個資料塊(data block)内可用于存儲索引資料的空間等于資料塊容量減去資料塊管理開銷(overhead),索引條目管理開銷(entry overhead),rowid,及記錄每個索引值長度的 1 位元組(byte)。

當使用者建立索引時,oracle 取得所有被索引列的資料并進行排序,之後将排序後索引值和與此值相對應的 rowid 按照從下到上的順序加載到索引中。例如,以下語句:

create index employees_last_name on employees(last_name);

oracle 先将 employees 表按

last_name 列排序,再将排序後的 列及相應的 rowid 按從下到上的順序加載到索引中。使用此索引時,oracle 可以快速地搜尋已排序的last_name 值,并使用相應的 rowid 去定位包含使用者所查找的last_name 值的資料行。

oracle 使用平衡樹(b-tree)存儲索引以便提升資料通路速度。當不使用索引時,使用者必須對資料進行順序掃描(sequential scan)來查找指定的值。如果有 n 行資料,那麼平均需要掃描的行為 n/2。是以當資料量增長時,這種方法的開銷将顯著增長。

如果将一個已排序的值列(list of the values)劃分為多個區間(range),每個區間的末尾包含指向下個區間的指針(pointer),而搜尋樹(search tree)中則儲存指向每個區間的指針。此時在 n 行資料中查詢一個值所需的時間為 log(n)。這就是 oracle 索引的基本原理。

在一個平衡樹索引(b-tree index)中,最底層的索引塊(葉塊(leaf block))存儲了被索引的資料值,以及對應的 rowid。葉塊之間以雙向連結清單的形式互相連接配接。位于葉塊之上的索引塊被稱為分支塊(branch block),分枝塊中包含了指向下層索引塊的指針。如果被索引的列存儲的是字元資料(character data),那麼索引值為這些字元資料在目前資料庫字元集(database

character set)中的二進制值(binary value)。

對于唯一索引(unique index),每個索引值對應着唯一的一個 rowid。對于非唯一索引(nonunique index),每個索引值對應着多個已排序的 rowid。是以在非唯一索引中,索引資料是按照索引鍵(index key)及 rowid 共同排序的。鍵值(key value)全部為null 的行不會被索引,隻有簇索引(cluster index)例外。在資料表中,如果兩個資料行的全部鍵值都為

null,也不會與唯一索引相沖突。

有兩種類型的索引塊:

用于搜尋的分支塊(branch block)

用于存儲索引資料的葉塊(leaf block)

分支塊(branch block)中存儲以下資訊:

最小的鍵值字首(minimum key prefix),用于在(本塊的)兩個鍵值之間做出分支選擇

指向包含所查找鍵值的子塊(child block)的指針()

包含 n 個鍵值的分支塊(branch block)含有 n+1 個指針。鍵值及指針的數量同時還受索引塊(index block)容量的限制。

所有葉塊(leaf block)相對于其根分支塊(root branch block)的深度(depth)是相同的。葉塊用于存儲以下資訊:

資料行的鍵值(key value)

鍵值對應資料行的 rowid

所有的 鍵值-rowid 對(key and

rowid pair)都與其左右的兄弟節點(sibling)向連結(link),并按照(key,rowid)的順序排序。

平衡樹資料結構(b-tree structure)具有以下優勢:

平衡樹(b-tree)内所有葉塊(leaf block)的深度相同,是以擷取索引内任何位置的資料所需的時間大緻相同。

平衡樹索引(b-tree index)能夠自動保持平。

平衡樹内的所有塊容量平均在總容量的 3/4 左右。

在大區間(wide range)範圍内進行查詢時,無論比對個别值(exact match)還是搜尋一個區間(range search),平衡樹都能提供較好的查詢性能。

資料插入(insert),更新(update),及删除(delete)的效率較高,且易于維護鍵值的順序(key order)

大型表,小型表利用平衡樹進行搜尋的效率都較好,且搜尋效率不會因資料增長而降低。

索引唯一掃描(index unique scan)是效率最高的資料通路方式之一。從平衡樹索引(b-tree index)中擷取資料時将采用此種方式。當一個唯一索引(采用平衡樹結構)的全部列都包含在查詢條件中,且查詢體條件表達式均為等号(equality)時,優化器将選擇使用索引唯一掃描。 

當通路選擇性較大的資料(selective data)時 oracle 常進行索引區間掃描(index range scan)。掃描區間可以是封閉的(bounded)(兩端均封閉),也可以是不封閉的(unbounded)(一端或兩端均不封閉)。掃描所傳回的資料按照索引列的升序進行排列,對于索引值相同的行将按rowid 的升序排列。 

使用者利用鍵壓縮(key compression)可以将索引或索引表(index-organized table)中鍵值(column value)的部分内容進行壓縮,以便減少重複值帶來的存儲開銷。

一般來說,索引的一個鍵(key)通常由兩個片段(piece)構成:分組片段(grouping piece)及唯一片段(unique piece)。如果定義索引的鍵中不存在唯一片段,oracle 會以 rowid 的形式在此鍵的分組片段後添加一個唯一片段。鍵壓縮(key compression)就是将鍵的分組片段從鍵中拆分出來單獨存儲,供多個唯一片段使用。

5.8.9.1 索引鍵的字首和字尾

鍵壓縮(key compression)将一個索引鍵拆分為字首(prefix entry)(即分組片段(grouping piece))和字尾(suffix entry)(即唯一片段(unique piece))。壓縮是通過一個索引塊(index block)中的多個字尾共享一個字首來實作的。在平衡樹索引(b-tree index)中隻有位于葉塊(leaf block)的鍵會被壓縮。在分支塊(branch

block)内不必存儲鍵的字尾,是以其中的鍵也無需壓縮。

鍵壓縮(key compression)隻能在每個索引塊(index block)内分别實作,而不能跨多個索引塊。壓縮後每個索引行(index row)隻儲存字尾(suffix entry),而每個字尾将引用一個共享的字首(prefix entry),字尾與其共享的字首必須位于同一索引塊内。

預設情況下,字首(prefix entry)由除去最後一列之外的其他鍵列(key column)構成。例如,一個索引鍵(index key)由(column1,column2,column3)3 列構成,則預設的字首為(column1, column2)。如一組索引值為(1,2,3),(1,2,4),(1,2,7),(1,3,5),(1,3,4),(1,4,4),則其中重複出現的字首 (1,2),(1,3)

将被壓縮。

使用者也可以手工設定字首長度(prefix length),即字首所包含的列數。例如,如果使用者設定字首長度為 1,則在上述例子中,column1 為字首,(column2,column3)為字尾,其中重複出現的字首 1 将被壓縮。

非唯一索引(nonunique index)的最大字首長度(prefix length)為鍵列的個數,而唯一索引(unique index)的最大字首長度為鍵列的個數減 1。

應用鍵壓縮(key compression)後,生成索引時,如果一個鍵值(key value)的字首(prefix entry)在索引塊(index block)中不存在,此字首才會被寫入索引塊中。一個字首被寫入後立即就可以被此索引塊内的字尾(suffix entry)共享,直到所有引用此字首的字尾都被删除為止。

鍵壓縮(key compression)能夠節約大量存儲空間,是以使用者可以在一個索引塊(index block)記憶體儲更多的索引鍵(index key),進而減少 i/o,提高性能。

鍵壓縮(key compression)能夠減少索引所需的存儲空間,但索引掃描時需要重構(reconstruct)鍵值(key value),是以增加了 cpu 的負擔。此外鍵壓縮也會帶來一些存儲開銷,每個字首(prefix entry)需要 4 位元組(byte)的管理開銷。

鍵壓縮(key compression)在多種情況下都能夠發揮作用,例如:

對于非唯一索引(nonunique index),oracle 會在每個重複的索引鍵(index key)之後添加 rowid 以便區分。如果使用了鍵壓縮,在一個索引塊(index block)内,oracle 隻需将重複的索引鍵作為字首((prefix entry))存儲一次,并用各行的 rowid 作為字尾(suffix entry)。

唯一索引(nonunique index)中也存在相同的情況。例如唯一索引(stock_ticker,transaction_time)的含義是(項目,時間戳),通常數千條記錄中stock_ticker 的值是相同的,但她們對應的transaction_time 值各不相同。使用了鍵壓縮後,一個索引塊中每個

stock_ticker 值作為字首隻需存儲一次,而各個transaction_time 值則作為字尾存儲,并引用一個共享的stock_ticker 字首。

在一個包含 varray 或 nested table 資料類型(datatype)的索引表(index-organized table)中,這些collection 類型中各個元素(element)的對象辨別符(object identifier)是重複的。使用者可以使用鍵壓縮以避免重複存儲這些對象辨別符。

有些情況無法使用鍵壓縮(key compression)。例如,一個隻有一個索引鍵(index key)的唯一索引(unique index)就無法使用鍵壓縮,因為索引鍵中不存在可供共享的分組片段(grouping piece)。 

使用者可以建立逆序鍵索引(reverse key index),此處的逆序指索引列值(index key value)得各個位元組(byte)按倒序排列,而非索引列(index key)逆序排列。在 rac 環境中,使用這樣的排列方式可以避免由于對索引的修改集中在一小部分葉塊(leaf block)上而造成的性能下降。通過使索引的鍵值逆序排列,可以使插入操作分布在索引的全部葉塊中。

使用逆序鍵索引(reverse key index)後将無法對此索引進行索引區間掃描(index range scanning),因為在逆序鍵索引 中,詞彙上(lexically)相鄰的索引鍵(index key)在存儲上未必相鄰。是以在逆序鍵索引 上隻能進行确定鍵掃描(fetch-by-key scan)或全索引掃描(full-index scan)。

有些情況下,使用逆序鍵索引(reverse key index)可以令 rac 環境下的 oltp 應用效率更高。例如,為一個 e-mail 應用中的所有郵件進行索引:由于使用者可能儲存舊的郵件,是以索引必須做到既能快速通路最新郵件,也能快速通路舊郵件。

使用者使用 reverse 就可以輕易地建立逆序鍵索引(reverse key index)。在

create index語句中使用reverse 關鍵字作為建立索引的選項:

create index i on t (a,b,c) reverse;

使用者也可以在 rebuild 子句後添加

noreverse 關鍵字将一個逆序鍵索引(reverse key index)轉換為正常的索引:

alter index i rebuild noreverse;

如果 rebuild 子句後沒有使用

noreverse 關鍵字,那麼逆序鍵索引(reverse key index)被重建後仍将保持逆序。

索引的目标是為使用者提供指向包含特定鍵值(key value)的資料行的指針。在正常的索引中,oracle 将各行的鍵值及與此鍵值對應的一組 rowid 存儲在一起,進而實作了上述目标。而在位圖索引(bitmap index)中,隻需存儲每個鍵值的位圖(bitmap),而非一組 rowid。

位圖(bitmap)中的每一位(bit)對應一個可能的 rowid。如果某一位被置位(set),則表明着與此位對應的 rowid 所指向的行中 包含此位所代表的鍵值(key value)。oracle 通過一個映射函數(mapping function)将位資訊轉化為實際的 rowid,是以雖然位圖索引(bitmap index)内部的存儲結構與正常索引不同,但她同樣能實作正常索引的功能。當不同值的索引鍵的數量較少時,位圖索引的存儲效率相當高。

如果在 where 子句内引用的多個列上都建有位圖索引(bitmap index),那麼進行位圖索引掃描時(bitmap indexing)可以将各個位圖索引融合在一起。不滿足全部條件的行可以被預先過濾掉。是以使用位圖索引能夠極大地提高查詢的響應時間。

資料倉庫應用(data warehousing application)的特點是資料量巨大,執行的多為自定義查詢(ad hoc query),且并發事務較少。這種環境下使用位圖索引(bitmap index)具備如下優勢:

能夠減少大資料量自定義查詢的響應時間

與其他索引技術相比能夠節省大量存儲空間

即使硬體配置較低也能顯著提高性能

有利于并行 dml 和并行加載

為一個大表建立傳統的平衡樹索引(b-tree index)可能占用極大的存儲空間,索引有可能比資料表還要大數倍。而一個位圖索引(bitmap index)所占的空間比被索引資料還要小得多。

位圖索引(bitmap index)不适用于 oltp 系統,因為這樣的系統中存在大量對資料進行修改的并發事務。位圖索引主要用于資料倉庫系統中(data warehousing)的決策支援功能,在這種環境下使用者對資料的操作主要是查詢而非修改。

主要進行大于(greater than)或小于(less than)比較的列,不适宜使用位圖索引(bitmap index)。例如,where 子句中常會将 salary 列和一個值進行比較,此時更适合使用平衡樹索引(b-tree index)。位圖索引适用于等值查詢,尤其是存在 and,or,和not 等邏輯操作符的組合時。

位圖索引(bitmap index)是內建在 oracle 的優化器(optimizer)和執行引擎(execution engine)之中的。位圖索引也能夠和 oracle 中的其他執行方法(execution method)無縫地組合。例如,優化器可以在利用一個表的位圖索引和另一個表的平衡樹索引(b-tree index)對這兩張表進行哈希連接配接(hash join)。優化器能夠在位圖索引及其他可用的通路方法(例如正常的平衡樹索引,或全表掃描(full

table scan))中選擇效率最高的方式,同時考慮是否适合使用并行執行。

位圖索引(bitmap index)如同正常索引一樣,可以結合并行查詢(parallel query)和并行 dml(parallel dml)一起工作。建立于分區表(partitioned table)的位圖索引必須為本地索引(local index)。oracle 還支援并行地建立位圖索引,以及建立複合位圖索引。

在基數(cardinality)小的列上建立位圖索引(bitmap index)效果最好。所謂某列的基數小(low cardinality)是指此列中所有不相同的值的個數要小于總行數。如果某列中所有不相同的值的個數占總行數的比例小于 1%,或某列中值的重複數量在 100 個以上,那麼就可以考慮在此列上建立位圖索引。即便某列的基數較上述标準稍大,或值的重複數量較上述标準稍小,如果在一個查詢的where

子句中需要引用此列定義複雜的條件,也可以考慮在此列上建立位圖索引。

例如,一個表包含一百萬行資料,其中的一列包含一萬個不相同的值,就可以考慮在此列上建立位圖索引(bitmap index)。此列上位圖索引的查詢性能将超過平衡樹索引(b-tree index),當此列與其他列作為組合條件時效果尤為明顯。

平衡樹索引(b-tree index)适用于高基數的資料,即資料的可能值很多,例如customer_name 或

phone_number 列。在有些情況下,平衡樹索引所需的存儲空間可能比被索引資料還要大。如果使用得當,位圖索引将遠遠小于同等情況下的平衡樹索引。

對于自定義查詢(ad hoc query)或相似的應用,使用位圖索引(bitmap index)能夠顯著地提高查詢性能。查詢的where 子句中的and 和or 條件直接對位圖(bitmap)進行布爾運算(boolean operation)得到一個位圖結果集(resulting bitmap),而無需将所有的位圖轉換為

rowid。如果布爾操作後的結果集較小,那麼查詢就能夠迅速得到結果,而無需進行全表掃描(full table scan)。

與其他大多數索引不同,位圖索引(bitmap index)可以包含鍵值(key value)為

null 的行。将鍵值為空的行進行索引對有些 sql 語句是有用處的,例如包含count 聚合函數的查詢。

使用者可以在分區表(partitioned table)上建立位圖索引(bitmap index)。唯一的限制是位圖索引對分區表來說必須是本地的(local),而不能是全局索引(global index)。隻有非分區表才能使用全局位圖索引。

  除了建立在單個表之上的位圖索引(bitmap index),使用者還可以建立位圖連接配接索引(bitmap join index),此種索引是為了連接配接(join)兩個或多個資料表而建的。位圖連接配接索引(bitmap join index)可以預先将有連接配接關系的資料進行儲存,且所需的存儲空間較小。對于一個表的某列的每個值,位圖連接配接索引為其儲存其他表中與此值有連接配接關系的資料行的 rowid。在資料倉庫環境中,連接配接關系通常是維表(dimension

table)中的主鍵(primary key)與事實表(fact table)中的外鍵(foreign key)進行等值内連接配接(equi-inner join)。

        物化連接配接視圖(materialized join view)也是一種預先将連接配接物化的方法,但與之相比位圖連接配接索引(bitmap join index)所需的存儲空間更少。因為物化連接配接視圖不會壓縮事實表(fact table)中的 rowid。

<a target="_blank" href="http://www.jiagulun.com/blog-2-2158.html">http://www.jiagulun.com/blog-2-2158.html</a>