關於ORACLE資料庫索引

2021-07-22 20:16:05 字數 3783 閱讀 5323

許娟萍1999.03.22

一、索引

索引不是執行oracle所必需的,但它能夠加快查詢速度。當執行同樣的查詢時,若有利用索引,oracle首先在索引中查詢,由於索引是按大小排列的,因此能很快找到查詢結果。

乙個表的單個索引最多可以包含16個列。索引太多的代價是降低插入新行的速度:每做一次insert操作,每個索引也都要增加乙個新專案。

如果表主要只用於查詢,那麼索引多列的唯一消耗就是磁碟空間。但這時索引較之空間的浪費更有價值。

二、在資料庫中放置索引

通過將索引賦予乙個指定的表空間,使用者可以指定乙個表的索引放置的位置。乙個表空間就是磁碟上用於儲存表和索引的一段空間,乙個資料庫可以有多個表空間,每個表空間都有各自的名稱。乙個表的索引應該放置在與資料表空間上下不同的物理磁碟上,這樣可以減少表空間檔案之間的磁碟爭用。

三、使用索引操作

在oracle中,有兩大類索引:唯一索引對於被索引列,索引表中每一行

包含乙個唯一值,和非唯一索引行中的索引值可重複。從索引中讀取資料的操作取決於使用的索引型別和查詢中訪問索引的方法。

請瀏覽一下表charge:

create table charge

( recnum number(9) not null,

boxnum char(12),

callernum char(16),

callednum char(16),

begintime char(14),

ywtime number(5),

funcnum number(2)

);預設情況下,表charge上沒有索引生成。若我們假定列recnum是表charge中的主關鍵字—也就是說,它唯一的區別了每一行,這時就可以在表charge上定義主關鍵字約束以保證列recnum的唯一性。

無論何時乙個主關鍵字或唯一約束被生成,oracle將生成乙個唯一索引以保證列值的唯一性。以下所示的目錄alter table包含了using index子句來強迫索引被定位於表空間indexes中:

alter table charge

add constraint recnum_pk primary key (recnum)

using index tablespace indexes;

使用者也可以手工地在表charge中的其他列上記錄索引。例如,如果列begintime的值為非唯一的話,使用者可以通過命令create index在列上建立乙個非唯一索引。

create index charge$begintime

on charge(begintime)

tablespace indexes;

表charge上現有兩個索引:列recnum上的唯一索引和列begintime上的非唯一索引。在處理查詢的過程中,可以使用乙個或多個索引,這取決於查詢是如何編寫和執行的。

四、何時使用索引

1. 當設定乙個索引列為一特定值時在表charge中,列begintime具有乙個非唯一索引charge$begintime。乙個設定列begintime值為一定值的查詢將能夠使用索引charge$begintime。

例: select * from charge

where begintime=』19990322103000』;

2. 當對索引列指定一特定區間值時索引的使用並不需要指定明確的值。索引區間掃瞄操作可以掃瞄索引中的一段值。

在下面的查詢中,表charge中的列begintime被用於執行一段區間值的查詢(查詢1999/3/22日的計費話單):

例: select * from charge

where begintime like 『19990322

當對一列指定了一段值區間後,如果指定的第乙個字元是乙個萬用字元的話,索引在查詢中將不被使用。

例: select * from charge

where begintime like 『%0322103000』;

由於用作值比較的字串的首字母為萬用字元,索引不能被用於快速地尋找相關資料,所以乙個全表掃瞄將被執行。

3. 當在where子句中無任何函式在列上執行時

例: select * from charge

where substr(begintime,1,6)=』19990322』;

上例中的查詢將對錶charge執行全表掃瞄操作,因為有函式substr在列begintime上執行。

4. 當no is null或is not null選項用於索引列時null值(空值)並未在索引中存貯。所以,下列查詢將並不使用索引,索引對查詢的處理也沒有如何幫助。

例: select * from charge

where begintime is null;

由於begintime是查詢中的唯一的有限定條件的列,且此限定條件為

null(空)檢查,所以索引charge$begintime將不被使用,而執行全表訪問操作來處理查詢。

當is not null選項作用在乙個列時,列中所有的非空值被存貯在索引中,但是索引搜尋並不是有效率的。為了處理查詢,優化器需要從索引中讀取每個列值並通過訪問表來獲得索引返回的每一行內容。在多數情況下,對於從索引中返回的所有值,執行全表掃瞄操作比執行索引掃瞄效率更高。

所以,下面的查詢不應使用索引。

例: select * from charge

where begintime is not null;

5. 當等值條件被使用時

例: select * from charge

where begintime!=』19980322103000』;

當處理以上的查詢時,優化器將不能夠利用索引。索引被用於當值被設

定為另乙個值的情況—即當限定條件為等式時,而非不等式。

另乙個不等式的例子not in子句,當用於字查詢時:

例: select * from charge

where recnum not in

select recnum from charge

where begintime=』19990322103000』);

上例中的查詢將不能夠使用表charge中的列recnum上的索引,因為它並未設定為任何定值。

下例查詢中使用了in子句,因而可以使用在列recnum上的索引。

例: select * from charge

where recnum in

select recnum from charge

where begintime=』19990322103000』);

6. 當多列索引中的首列被設為定值時

索引可在單列或多列上建立。如果索引是生成在多列上,則只有在查詢中索引首列被用於限制條件時,索引才能夠被使用。如果查詢中僅對索引的非首列指定值限定條件,索引將不被用於查詢中。

7. 當使用max或min函式時

當在索引列上選擇max或min值時,優化器可以使用索引來快速地檢索列中的最大值或最小值。

例: select min(begintime) from charge;

8. 當索引是選擇性時

當使用成本優化器cbo選項時,優化器將對索引作出選擇以確定索引的使用是否會降低查詢執行的成本。

當索引是高度選擇性時,僅有一小部分記錄與每個不同的列值相關聯。例如,如果表中有100個記錄而對錶中乙個項有80個不同值,則此列上的索引選擇性為80/100=0.8。

選擇性越高,對於列中每個不同值,查詢返回的行資料個數越少。

在區間掃瞄中,每個不同值返回的行數是非常重要的。如果乙個索引的

選擇性較低,則用於檢索資料的多次索引區間掃瞄和rowid索引訪問操作可能較一次表的全表訪問操作需要更多工作。

建立Oracle資料庫索引的標準

在oracle資料庫中,建立索引雖然比較簡單。但是要合理的建立索引則比較困難了。筆者認為,在建立索引時要做到三個適當,即在適當的表上 適當的列上建立適當數量的索引。雖然這可以通過一句話來概括優化的索引的基本準則,但是要做到這一點的話,需要資料庫管理員做出很大的努力。具體的來說,要做到這個三個適當有如...

oracle資料庫入門

很多剛剛接觸oracle資料庫的初學者總是感覺oracle很難學,無從下手,漸漸的感覺對oracle很排斥,有的朋友找了本oracle是書也是一點也看不懂,或者看了前面幾章,還是不知道怎麼用。其實,從筆者的親身經歷來說,oracle入門很簡單,使用oracle的基本功能也是一件非常簡單的事情。但是想...

為什么有時Oracle資料庫不用索引來查詢資料

為什麼有時 oracle 資料庫不用索引來查詢資料 一 當你運用 sql 語言,向資料庫發布一條查詢語句時,oracle 將伴隨產生乙個執行計畫,也就是該語句將通過何種資料搜尋方案執行,是通過全表掃瞄 還是通過索引搜尋等其它方式。搜尋方案的選用與 oracle 的優化器息息相關。sql 語句的執行步...