當前位置:首頁 » 數據倉庫 » oracle資料庫索引的使用
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

oracle資料庫索引的使用

發布時間: 2022-05-13 08:09:51

A. oracle的sql索引使用

1,第一次查詢慢,以後就快了,主要是因為第一次要進行磁碟操作,以後數據被cache到內存中了,不在操作磁碟,所以就快了。
2,對於你說的這四種查詢,where條件中的a=a估計你是舉例子這樣寫的吧。實際上應該是a=變數A。其他的b,c,d也是這樣。那麼這種語句都是可以利用你說的復合索引的。如果是RBO優化器,這四句都應該用索引。但是oracle現在推薦的CBO優化器不能保證你都走索引。
3,到底用沒用索引,你可以從v$sqlaera中找到你的語句對應的hash_value,然後從v$sql_plan中找到語句的執行計劃,通過執行計劃確認你的語句是不是使用了索引。
具體語句你可以類似如下寫法:
select
hash_value,sql_text
from
v$sqlarea
where
upper(sql_text)
like
'%你需要查找的sql語句的特徵片段%'
select
*
from
v$sql_plan
where
hash_value
=
上一句查到的hash_value

B. oracle 資料庫如何建立索引 如何用索引

創建索引語法:

CREATE [UNIQUE] | [BITMAP] INDEX index_name

--unique表示唯一索引

ON table_name([column1 [ASC|DESC],column2

--bitmap,創建點陣圖索引

[ASC|DESC],…] | [express])[TABLESPACE tablespace_name][PCTFREE n1]

--指定索引在數據塊中空閑空間

[STORAGE (INITIAL n2)][NOLOGGING]

--表示創建和重建索引時允許對表做DML操作,默認情況下不應該使用

[NOLINE][NOSORT];

--表示創建索引時不進行排序,默認不適用,如果數據已經是按照該索引順序排列的可以使用

(2)oracle資料庫索引的使用擴展閱讀:

1、如果有兩個或者以上的索引,其中有一個唯一性索引,而其他是非唯一,這種情況下oracle將使用唯一性索引而完全忽略非唯一性索引

2、至少要包含組合索引的第一列(即如果索引建立在多個列上,只有它的第一個列被where子句引用時,優化器才會使用該索引)

3、小表不要簡歷索引

4、對於基數大的列適合建立B樹索引,對於基數小的列適合簡歷點陣圖索引

5、列中有很多空值,但經常查詢該列上非空記錄時應該建立索引

6、經常進行連接查詢的列應該創建索引

7、使用create index時要將最常查詢的列放在最前面

8、LONG(可變長字元串數據,最長2G)和LONG RAW(可變長二進制數據,最長2G)列不能創建索引

9、限製表中索引的數量(創建索引耗費時間,並且隨數據量的增大而增大;索引會佔用物理空間;當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,降低了數據的維護速度)

C. oracle資料庫中什麼情況下使用基於函數的索引

1.
b-tree索引
oracle資料庫中最常見的索引類型是b-tree索引,也就是b-樹索引,以其同名的計算科學結構命名。create
index語句時,默認就是在創建b-tree索引。沒有特別規定可用於任何情況。
2.
點陣圖索引(bitmap
index)
點陣圖索引特定於該列只有幾個枚舉值的情況,比如性別欄位,標示欄位比如只有0和1的情況。
3.
基於函數的索引
比如經常對某個欄位做查詢的時候是帶函數操作的,那麼此時建一個函數索引就有價值了。
4.
分區索引和全局索引
這2個是用於分區表的時候。前者是分區內索引,後者是全表索引
5.
反向索引(reverse)
這個索引不常見,但是特定情況特別有效,比如一個varchar(5)位欄位(員工編號)含值
(10001,10002,10033,10005,10016..)
這種情況默認索引分布過於密集,不能利用好伺服器的並行
但是反向之後10001,20001,33001,50001,61001就有了一個很好的分布,能高效的利用好並行運算。
6.hash索引
hash索引可能是訪問資料庫中數據的最快方法,但它也有自身的缺點。集群鍵上不同值的數目必須在創建hash集群之前就要知道。需要在創建hash集群的時候指定這個值。使用hash索引必須要使用hash集群。

D. oracle的索引有幾種

Oracle 提供了多種不同類型的索引以供使用。簡單地說, Oracle 中包括如下索引:
1、 B* 樹索引
這些是我所說的 「 傳統 「 索引。到目前為止,這是 Oracle 和大多數其他資料庫中最常用的索引。 B* 樹的構造類似於二叉樹,能根據鍵提供一行或一個行集的快速訪問,通常只需很少的讀操作就能找到正確的行。不過,需要注意重要的一點, 」 B* 樹 「 中的 」 B 「 不代表二叉( binary ),而代表平衡( b alanced )。B* 樹索引並不是一顆二叉樹,這一點在介紹如何在磁碟上物理地存儲 B* 樹時就會了解到。 B* 樹索引有以下子類型:
索引組織表( index organized table ):索引組織表以 B* 樹結構存儲。堆表的數據行是以一種無組織的方式存儲的(只要有可用的空間,就可以放數據),而 IOT 與之不同, IOT 中的數據要按主鍵的順序存儲和排序。對應用來說, IOT 表現得與 「 常規 「 表並無二致;需要使用 SQL 來正確地訪問 IOT 。 IOT 對信息獲取、空間系統和 OLAP 應用最為有用。 IOT 在上一章已經詳細地討論過。
B*樹聚簇索引( B*tree cluster index )這些是傳統 B* 樹索引的一個變體(只是稍有變化)。 B* 樹聚簇索引用於對聚簇鍵建立索引(見第 11. 章中 「 索引聚簇表 「 一節),所以這一章不再討論。在傳統 B* 樹中 ,鍵都指向一行;而 B* 樹聚簇不同,一個聚簇鍵會指向一個塊,其中包含與這個聚簇鍵相關的多行。
降序索引( descending index ):降序索引允許數據在索引結構中按 「 從大到小 「 的順序(降序)排序,而不是按 」 從小到大 「 的順序(升序)排序。我們會解釋為什麼降序索引很重要,並說明降序索引如何工作。
反向鍵索引( reverse key index ):這也是 B* 樹索引,只不過鍵中的位元組會 「 反轉 「 。利用反向鍵索引,如果索引中填充的是遞增的值,索引條目在索引中可以得到更均勻的分布。例如,如果使用一個序列來生成主鍵,這個序列將生成諸如 987500 、 987501 、 987502 等值。這些值是順序的,所以倘若使用一 個傳統的 B* 樹索引,這些值就可能放在同一個右側塊上,這就加劇了對這一塊的競爭。利用反向鍵, Oracl e則會邏輯地對 205789 、 105789 、 005789 等建立索引。 Oracle 將數據放在索引中之前,將先 把所存儲數據的位元組反轉,這樣原來可能在索引中相鄰放置的值在位元組反轉之後就會相距很遠。通過反轉位元組,對索引的插入就會分布到多個塊上。

2、 點陣圖索引( bitmap index )
在一顆 B* 樹中,通常索引條目和行之間存在一種一對一的關系:一個 索引條目就指向一行。而對於點陣圖索引,一個索引條目則使用一個點陣圖同時指向多行。點陣圖索引適用於高度重復而且通常只讀的數據(高度重復是指相對於表中的總行數,數據只有很少的幾個不同值)。考慮在一 個有 100 萬行的表中,每個列只有 3 個可取值: Y 、 N 和 NULL 。舉例來說,如果你需要頻繁地統計多少行有值Y ,這就很適合建立點陣圖索引。不過並不是說如果這個表中某一列有 11.000 個不同的值就不能建立點陣圖索引,這一列當然也可以建立 點陣圖索引。在一個 OLTP 資料庫中,由於存在並發性相關的問題,所以不能考慮使用點陣圖索引(後面我們就會討論這一點)。注意,點陣圖索引要求使用 Oracle 企業版或個人版。
點陣圖聯結索引( bitmap join index ):這為索引結構(而不是表)中的數據提供了一種逆規范化的 方法。例如,請考慮簡單的 EMP 和 DEPT 表。有人可能會問這樣一個問題: 「 多少人在位於波士頓的部門工作 ?「 EMP 有一個指向 DEPT 的外鍵,要想統計 LOC 值為 Boston 的部門中的員工人數,通常必須完成表聯結,將 LOC 列聯結至 EMP 記錄來回答這個問題。通過使用點陣圖聯結索引,則可以在 EMP 表上對 LOC 列建立索引 。
3、 基於函數的索引( function-based index )
這些就是 B* 樹索引或點陣圖索引,它將一個函數計算得到的結果存儲在行的列中,而不是存儲列數據本身。可以把基於函數的索引看作一個虛擬列(或派生列)上的索引,換句話說,這個列並不物理存儲在表中。基於函數的索引可以用於加快形如 SELECT * FROM T W HERE FUNCTION(DATABASE_COLUMN) = SAME_VALUE 這樣的查詢,因為值 FUNCTION(DATABASE_COLUMN) 已經提前計算並存儲在索引中。
4、 應用域索引( application domain index )
應用域索引是你自己構建和存儲的索引,可能存儲在Oracle 中,也可能在 Oracle 之外。你要告訴優化器索引的選擇性如何,以及執行的開銷有多大,優化器則會根據你提供的信息來決定是否使用你的索引。 Oracle 文本索引就是應用域索引的一個例子;你也可 以使用構建 Oracle 文本索引所用的工具來建立自己的索引。需要指出,這里創建的 「 索引 「 不需要使用傳統的索引結構。例如, Oracle 文本索引就使用了一組表來實現其索引概念。

5、HASH索引
使用HASH索引必須要使用HASH群集。建立一個群集或HASH群集的同時,也就定義了一個群集鍵。這個鍵告訴Oracle如何在群集上存儲表。在存儲數據時,所有與這個群集鍵相關的行都被存儲在一個資料庫塊上。若數據都存儲在同一個資料庫塊上,並且使用了HASH索引,Oracle就可以通過執行一個HASH函數和I/O來訪問數據——而通過適用一個二元高度為4的B-樹索引來訪問數據,則需要在檢索數據時使用4個I/O。
技巧:HASH索引在有限制條件(需要指定一個確定的值而不是一個值范圍)的情況下非常有用。
6、分區索引
分區索引就是簡單地把一個索引分成多個片斷,這樣可以訪問更小的片斷,並且可以把這些片斷分別存放在不同的硬碟上(避免I/O問題)。B-數索引和點陣圖索引都可以被分區,HASH索引不可以被分區。
有兩種類型的分區索引:本地分區索引和全局分區索引。每個類型都有兩個子類型,有前綴索引和無前綴索引。如果使用了點陣圖索引就必須是本地索引。
把索引分區最主要的原因是可以減少所需讀取的索引的大小,另外把分區放在不同的表空間中可以提高分區的可用性和可靠性。

E. 如何更好的使用Oracle全文索引

不使用Oracle text功能,也有很多方法可以在Oracle資料庫中搜索文本.可以使用標準的INSTR函數和LIKE操作符實現。
SELECT *FROM mytext WHERE INSTR (thetext, 'Oracle') > 0;
SELECT * FROM mytext WHERE thetext LIKE '%Oracle%';

有很多時候,使用instr和like是很理想的, 特別是搜索僅跨越很小的表的時候.然而通過這些文本定位的方法將導致全表掃描,對資源來說消耗比較昂貴,而且實現的搜索功能也非常有限,因此對海量的文本數據進行搜索時,建議使用oralce提供的全文檢索功能 建立全文檢索的步驟步驟一 檢查和設置資料庫角色首先檢查資料庫中是否有CTXSYS用戶和CTXAPP腳色。如果沒有這個用戶和角色,意味著你的資料庫創建時未安裝intermedia功能。你必須修改資料庫以安裝這項功能。 默認安裝情況下,ctxsys用戶是被鎖定的,因此要先啟用ctxsys的用戶。 步驟二 賦權 在ctxsys用戶下把ctx_ddl的執行許可權賦於要使用全文索引的用戶,例:
grant execute on ctx_ddl to pomoho;

步驟三 設置詞法分析器(lexer)
Oracle實現全文檢索,其機制其實很簡單。即通過Oracle專利的詞法分析器(lexer),將文章中所有的表意單元(Oracle 稱為 term)找出來,記錄在一組 以dr$開頭的表中,同時記下該term出現的位置、次數、hash 值等信息。檢索時,Oracle 從這組表中查找相應的term,並計算其出現頻率,根據某個演算法來計算每個文檔的得分(score),即所謂的『匹配率』。而lexer則是該機制的核心,它決定了全文檢索的效率。Oracle 針對不同的語言提供了不同的 lexer, 而我們通常能用到其中的三個:
n basic_lexer: 針對英語。它能根據空格和標點來將英語單詞從句子中分離,還能自動將一些出現頻率過高已經失去檢索意義的單詞作為『垃圾』處理,如if , is 等,具有較高的處理效率。但該lexer應用於漢語則有很多問題,由於它只認空格和標點,而漢語的一句話中通常不會有空格,因此,它會把整句話作為一個 term,事實上失去檢索能力。以『中國人民站起來了』這句話為例,basic_lexer 分析的結果只有一個term ,就是『中國人民站起來了』。此時若檢索『中國』,將檢索不到內容。
n chinese_vgram_lexer: 專門的漢語分析器,支持所有漢字字元集(ZHS16CGB231280 ZHS16GBK ZHT32EUC ZHT16BIG5 ZHT32TRIS ZHT16MSWIN950 ZHT16HKSCS UTF8 )。該分析器按字為單元來分析漢語句子。『中國人民站起來了』這句話,會被它分析成如下幾個term: 『中』,『中國』,『國人』,『人民』,『民站』,『站起』,起來』,『來了』,『了』。可以看出,這種分析方法,實現演算法很簡單,並且能實現『一網打盡』,但效率則是差強人意。
n chinese_lexer: 這是一個新的漢語分析器,只支持utf8字元集。上面已經看到,chinese vgram lexer這個分析器由於不認識常用的漢語詞彙,因此分析的單元非常機械,像上面的『民站』,『站起』在漢語中根本不會單獨出現,因此這種term是沒有意義的,反而影響效率。chinese_lexer的最大改進就是該分析器 能認識大部分常用漢語詞彙,因此能更有效率地分析句子,像以上兩個愚蠢的單元將不會再出現,極大 提高了效率。但是它只支持 utf8, 如果你的資料庫是zhs16gbk字元集,則只能使用笨笨的那個Chinese vgram lexer.
如果不做任何設置,Oracle 預設使用basic_lexer這個分析器。要指定使用哪一個lexer, 可以這樣操作:
第一. 當前用戶下下建立一個preference(例:在pomoho用戶下執行以下語句)
exec ctx_ddl.create_preference ('my_lexer', 'chinese_vgram_lexer');

第二. 在建立全文索引索引時,指明所用的lexer:
CREATE INDEX myindex ON mytable(mycolumn) indextype is ctxsys.context

parameters('lexer my_lexer');

這樣建立的全文檢索索引,就會使用chinese_vgram_lexer作為分析器。
步驟四 建立索引
通過以下語法建立全文索引
CREATE INDEX [schema.]index on [schema.]table(column) INDEXTYPE IS ctxsys.context [ONLINE]

LOCAL [(PARTITION [partition] [PARAMETERS('paramstring')]

[, PARTITION [partition] [PARAMETERS('paramstring')]])]

[PARAMETERS(paramstring)] [PARALLEL n] [UNUSABLE];
例:

CREATE INDEX ctx_idx_menuname ON pubmenu(menuname)
indextype is ctxsys.context parameters('lexer my_lexer')

步驟五 使用索引
使用全文索引很簡單,可以通過:
select * from pubmenu where contains(menuname,'上傳圖片')>0
全文索引的種類
建立的Oracle Text索引被稱為域索引(domain index),包括4種索引類型:
l CONTEXT
2 CTXCAT
3 CTXRULE
4 CTXXPATH
依據你的應用程序和文本數據類型你可以任意選擇一種。
對多欄位建立全文索引
很多時候需要從多個文本欄位中查詢滿足條件的記錄,這時就需要建立針對多個欄位的全文索引,例如需要從pmhsubjects(專題表)的 subjectname(專題名稱)和briefintro(簡介)上進行全文檢索,則需要按以下步驟進行操作:
Ø 建議多欄位索引的preference
以ctxsys登錄,並執行:
EXEC ctx_ddl.create_preference(' ctx_idx_subject_pref',

'MULTI_COLUMN_DATASTORE');

Ø 建立preference對應的欄位值(以ctxsys登錄)

EXEC ctx_ddl.set_attribute(' ctx_idx_subject_pref ','columns','subjectname,briefintro');

Ø 建立全文索引
CREATE INDEX ctx_idx_subject ON pmhsubjects(subjectname)
INDEXTYPE ISctxsys.CONTEXT PARAMETERS('DATASTORE ctxsys.ctx_idx_subject_pref lexer my_lexer')
Ø 使用索引
select * from pmhsubjects where contains(subjectname,'李宇春')>0

全文索引的維護
對於CTXSYS.CONTEXT索引,當應用程序對基表進行DML操作後,對基表的索引維護是必須的。索引維護包括索引同步和索引優化。
在索引建好後,我們可以在該用戶下查到Oracle自動產生了以下幾個表:(假設索引名為myindex):
DR$myindex$I、DR$myindex$K、DR$myindex$R、DR$myindex$N其中以I表最重要,可以查詢一下該表,看看有什麼內容:
SELECT token_text, token_count FROM dr$i_rsk1$I WHERE ROWNUM <= 20;

這里就不列出查詢接過了。可以看到,該表中保存的其實就是Oracle 分析你的文檔後,生成的term記錄在這里,包括term出現的位置、次數、hash值等。當文檔的內容改變後,可以想見這個I表的內容也應該相應改變,才能保證Oracle在做全文檢索時正確檢索到內容(因為所謂全文檢索,其實核心就是查詢這個表)。這就用到sync(同步) 和 optimize(優化)了。
同步(sync): 將新的term 保存到I表;
優化(optimize): 清除I表的垃圾,主要是將已經被刪除的term從I表刪除。
當基表中的被索引文檔發生insert、update、delete操作的時候,基表的改變並不能馬上影響到索引上直到同步索引。可以查詢視圖 CTX_USER_PENDING查看相應的改動。例如:
SELECT pnd_index_name, pnd_rowid,
TO_CHAR (pnd_timestamp, 'dd-mon-yyyy hh24:mi:ss') timestamp
FROM ctx_user_pending;
該語句的輸出類似如下:
PND_INDEX_NAME PND_ROWID TIMESTAMP
------------------------------ ------------------ --------------------
MYINDEX AAADXnAABAAAS3SAAC 06-oct-1999 15:56:50

同步和優化方法: 可以使用Oracle提供的ctx_ddl包同步和優化索引
一. 對於CTXCAT類型的索引來說, 當對基表進行DML操作的時候,Oracle自動維護索引。對文檔的改變馬上反映到索引中。CTXCAT是事務形的索引。
索引的同步
在對基表插入,修改,刪除之後同步索引。推薦使用sync同步索引。語法:
ctx_ddl.sync_index(
idx_name IN VARCHAR2 DEFAULT NULL
memory IN VARCHAR2 DEFAULT NULL,
part_name IN VARCHAR2 DEFAULT NULL
parallel_degree IN NUMBER DEFAULT 1);
idx_name 索引名稱
memory 指定同步索引需要的內存。默認是系統參數DEFAULT_INDEX_MEMORY 。

指定一個大的內存時候可以加快索引效率和查詢速度,且索引有較少的碎片
part_name 同步哪個分區索引。
parallel_degree 並行同步索引。設置並行度。
例如:
同步索引myindex:Exec ctx_ddl.sync_index ('myindex');
實施建議:建議通過oracle的job對索引進行同步
索引的優化
經常的索引同步將會導致你的CONTEXT索引產生碎片。索引碎片嚴重的影響了查詢的反應速度。你可以定期優化索引來減少碎片,減少索引大小,提高查詢效率。
當文本從表中刪除的時候,Oracle Text標記刪除的文檔,但是並不馬上修改索引。因此,就的文檔信息占據了不必要的空間,導致了查詢額外的開銷。你必須以FULL模式優化索引,從索引中刪除無效的舊的信息。這個過程叫做垃圾處理。當你經常的對表文本數據進行更新,刪除操作的時候,垃圾處理是很必要的。
exec ctx_ddl.optimize_index ('myidx', 'full');
實施建議:每天在系統空閑的時候對全文索引進行相應的優化,以提高檢索的效率
P.S.定時優化索引
3.定時優化同步域索引
創建定時任務,定期優化和同步域索引
SQL> create or replace procere hsp_sync_index as
2 begin
3 ctx_ddl.sync_index('id_cont_msg');
4 end;
5 /

Procere created.

Elapsed: 00:00:00.08
SQL> VARIABLE jobno number;
SQL> BEGIN
2 DBMS_JOB.SUBMIT(:jobno,'hsp_sync_index();',
3 SYSDATE, 'SYSDATE + (1/24/4)');
4 commit;
5 END;
6 /

PL/SQL procere successfully completed.

Elapsed: 00:00:00.27
SQL> create or replace procere hsp_optimize_index as
2 begin
3 ctx_ddl.optimize_index('id_cont_msg','FULL');
4 end;
5 /

SQL> VARIABLE jobno number;
SQL> BEGIN
2 DBMS_JOB.SUBMIT(:jobno,'hsp_optimize_index();',
3 SYSDATE, 'SYSDATE + 1');
4 commit;
5 END;
6 /
Procere created.

Elapsed: 00:00:00.03

PL/SQL procere successfully completed.

Elapsed: 00:00:00.02
SQL>

F. oracle資料庫添加索引怎麼使用

索引建立代碼:

CREATEINDEX命令語法:

CREATEINDEX
CREATE[unique]INDEX[user.]index
ON[user.]table(column[ASC|DESC][,column
[ASC|DESC]]...)
[CLUSTER[scheam.]cluster]
[INITRANSn]
[MAXTRANSn]
[PCTFREEn]
[STORAGEstorage]
[TABLESPACEtablespace]
[NOSORT]
Advanced

其中:
schemaORACLE模式,預設即為當前帳戶
index索引名
table創建索引的基表名
column基表中的列名,一個索引最多有16列,long列、longraw
列不能建索引列
DESC、ASC預設為ASC即升序排序
CLUSTER指定一個聚簇(Hashcluster不能建索引)
INITRANS、MAXTRANS指定初始和最大事務入口數
Tablespace表空間名
STORAGE存儲參數,同createtable中的storage.
PCTFREE索引數據塊空閑空間的百分比(不能指定pctused)
NOSORT不(能)排序(存儲時就已按升序,所以指出不再排序)

G. oracle資料庫索引種類,分別什麼情況下使用

1. b-tree索引
Oracle資料庫中最常見的索引類型是b-tree索引,也就是B-樹索引,以其同名的計算科學結構命名。CREATE
INDEX語句時,默認就是在創建b-tree索引。沒有特別規定可用於任何情況。
2. 點陣圖索引(bitmap index)
點陣圖索引特定於該列只有幾個枚舉值的情況,比如性別欄位,標示欄位比如只有0和1的情況。
3. 基於函數的索引
比如經常對某個欄位做查詢的時候是帶函數操作的,那麼此時建一個函數索引就有價值了。
4. 分區索引和全局索引
這2個是用於分區表的時候。前者是分區內索引,後者是全表索引
5. 反向索引(REVERSE)
這個索引不常見,但是特定情況特別有效,比如一個varchar(5)位欄位(員工編號)含值
(10001,10002,10033,10005,10016..)
這種情況默認索引分布過於密集,不能利用好伺服器的並行
但是反向之後10001,20001,33001,50001,61001就有了一個很好的分布,能高效的利用好並行運算。
6.HASH索引
HASH索引可能是訪問資料庫中數據的最快方法,但它也有自身的缺點。集群鍵上不同值的數目必須在創建HASH集群之前就要知道。需要在創建HASH集群的時候指定這個值。使用HASH索引必須要使用HASH集群。

H. 請教: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列。

I. Oracle索引的概念及作用

在oracle中,索引是一種供伺服器在表中快速查找一個行的資料庫結構。在資料庫中建立索引主要有以下作用。(1)快速存取數據。(2)既可以改善資料庫性能,又可以保證列值的唯一性。(3)實現表與表之間的參照完整性(4)在使用orderby、groupby子句進行數據檢索時,利用索引可以減少排序和分組的時間。

J. Oracle資料庫中如何選擇合適的索引類型

憑借字典的目錄,我們可以非常迅速的找到我們所需要的條目。資料庫也是如此。憑借Oracle資料庫的索引,相關語句可以迅速的定位記錄的位置,而不必去定位整個表。 雖然說,在表中是否創建索引,不會影響到Oracle資料庫的使用,也不會影響資料庫語句的使用。這就好像即使字典沒有目錄的話,用戶仍然可以使用它一樣。可是,若字典沒有目錄,那麼可想而知,用戶要查某個條目的話,其不得不翻遍整本字典。資料庫也是如此。若沒有建立相關索引的話,則資料庫在查詢記錄的時候,不得不去查詢整個表。當表中的記錄比較多的時候,其查詢效率就會很低。所以,合適的索引,是提高資料庫運行效率的一個很好的工具。 不過,並不是說表上的索引越多越好。過之而不及。故在資料庫設計過程中,還是需要為表選擇一些合適的索引。寧缺勿濫,這是建立索引時的一個遵循標准。在理論上,雖然一個表可以設置無限的索引。但是,資料庫管理員需要知道,表中的索引越多,維護索引所需要的開銷也就越大。每當數據表中記錄有增加、刪除、更新變化的時候,資料庫系統都需要對所有索引進行更新。故資料庫表中的索引絕對不是多多益善。具體來說,在索引建立上,筆者對大家有如下建議。 建議一:在基數小的欄位上要善於使用點陣圖索引。 基數是點陣圖索引中的一個基本的定義,它是指資料庫表中某個欄位內容中不重復的數值。如在員工信息表中的性別欄位,一般就只有男跟女兩個值,所以,其基數為2;婚姻狀況欄位的話,則其只有已婚、未婚、離婚三種狀態,其基數就為3;民族一覽內也是只有有限的幾個值。 對於要查詢基數小的欄位,如現在用戶想查找所有婚姻狀況為「已婚」的「女性」時,利用點陣圖索引可以提高查詢的效率。這主要是因為標准索引是通過在索引中保存排序過的索引列以及對應的ROWID來實現的。若我們在基數小的列上建立標准索引的話,則其會返回大量的記錄。 而當我們在創建點陣圖索引的時候,在Oracle會對整個表進行掃描,並且會為索引列的每個取值建立一個點陣圖。若內容相同,則在點陣圖上會以一個相同的數字表示。此時,若這個欄位的基數比較小的話,則若需要實現對整個欄位的查詢的話,效率就會非常的高。因為此時,資料庫只要點陣圖中數字相同的內容找出來即可。 除了在數據表某列基數比較小的情況下,採用點陣圖索引外,我們往往在一些特殊的情況下,也會建議採用點陣圖索引。最常見的情況是,在Where限制條件中,若我們多次採用AND或者OR條件時,也建議採用點陣圖索引。因為當一個查詢飲用了一些部署了點陣圖索引的列的時候,這些點陣圖可以很方便的與AND或者Or 運算符操作結合以快速的找出用戶所需要的記錄。 但是,這里要注意,不是在條件語句中包含運算符的時候,採用點陣圖索引都能夠提供比較高的效率。一般來說,只有AND 或者OR運算符的時候,點陣圖索引才會比較具有優勢。若此時用戶採用大於號或者不等於號作為條件語句中的限制條件的時候,則往往採用標准索引具有更大的優勢。 所以,筆者在資料庫設置中,一般只有在三種情況下才採用點陣圖索引。一是列的基數比較小,而有可能需要根據這些欄位的內容查找相關的記錄;二是在條件語句中,用到了AND或者OR運算符的時候。除了這兩種情況外,最好能夠採用其他適合的索引。第三種情況是,需要用到NULL作為查詢的限制條件。因為標准查詢一般情況下,會忽略所有的NULL值列。也就是說,若需要查詢「所有沒有身份證號碼」的員工的信息的時候,標准索引並不能夠起到加速查詢速度的作用。此時,就需要採用點陣圖索引。因為點陣圖索引會記錄相關的NULL值列信息。 建議二:創建索引的一些限制條件。 並不說,表或者列建立的索引越多越好。相反,索引建的越多,有時會反而會影響資料庫運行的整體性能。所以,在建立索引的時候,仍然會有一些限制條件。 一是不要對一些記錄內容比較少的表建立索引。在一個應用系統設計的時候,如設計一個ERP系統的資料庫,其雖然有幾千張表。但是,並不是每張表都有大量記錄的。相反,其中有近一半左右的數據表,可能其存儲的數據不會超過百條。如員工登陸帳戶密碼表、企業部門信息表等等。對於這些記錄內容比較少的表,我們建立最好不要為其建立索引。無論是表上的,還是欄位上,都不要建立索引。 二是若表中的內容比較大,但是,這個表基本上不怎麼查詢的時候,則只需要在表上建立索引即可;而不需要在欄位上建立索引。如現在在ERP系統中,有一張表是「AD_Table」。其存儲的是這個資料庫中相關表的信息。這張表只有在資料庫設計的時候才會用到。故這張表中的記錄雖然比較多,但是由於用戶用的比較少,所以,一般沒有必要為這張表建立列級別上的索引。而直接用表索引來代替。 三是在一些NULL欄位上,要根據實際情況來判斷是否要建立索引。如現在有一張人事檔案的表格,其上面有兩個欄位,分別為「身份證號碼」與「地區」。有時會為了某個原因,企業需要所有員工都在系統中登記他們的身份證號碼,以方便他們辦工資卡、社會保險等等。所以人事管理可能需要經常的查詢系統,看看有沒有沒有身份證號碼的員工信息。此時,就需要利用條件「IS NULL」來查詢我們所需要的記錄。故為了提高查詢效率,若某個記錄可能為空,並且經常需要以NULL為條件進行查詢的時候,則最好給這個欄位添加一個索引,並且最好建立點陣圖索引。相反,若雖然可能會以NULL這個條件作為查詢的限制語句,但是,用的不是很多的時候,則就沒有必要為其建立索引。 建議三:多表連接查詢的索引設計。 如現在有一個人事管理系統。人事經理想知道員工的社保繳納情況。他需要知道員工的姓名、職務、戶籍性質(農民戶口跟居民戶口費用不一樣)、繳納的情況等等。但是,這些信息包含在不同的表中。因為為了提高資料庫的性能,在表中存儲的可能只是某些序號,而不是具體的內容。如在社保表中,存儲的是員工對應的編號,而不是員工的名字。所以,要得到這份報表的話,就可能需要關聯員工基本信息表、公司組織結構表等表格,才能夠查詢到用戶所需要的內容。 為此,就需要利用Join語句,把這些表格關聯起來。為了提高資料庫的查詢效率,這些用來關聯的欄位,最好能夠建立索引。這可以顯著的提高查詢的速度。 建議四:在表的更新速度與查詢速度之間尋求一個平衡點。 眾所周知,索引本身並不影響資料庫的使用,其主要是為了提高資料庫的查詢效率。但是,由於當資料庫的表中的數據更新的時候,包括記錄的增加、刪除、更改等等,都會對雖有的索引進行更新。 很明顯,索引雖然可以提高查詢速度。但是,也會對一些表的更新操作產生不良的影響。當在表中建立的索引越多,這個不利影響也會越大。故資料庫管理員在設置索引的時候,還需要注意,在這兩個之間需要一個均衡點。 按照一般的理論來說,當某個表多數用來查詢、更新相對來說比較上的話,則要多多採用索引。相反,當某個表記錄更新居主導,查詢相對來說比較少的話,則不要建立太多的索引,避免對更新的速度差生不利影響。