如果查詢結(jié)果僅為一行或很少幾行時(shí)(高選擇性high selectivity),利用索引進(jìn)行查詢會(huì)大大提高效率。相比之下,如果沒有索引,查詢則只能順序掃描整個(gè)表。在OLTP環(huán)境下,事務(wù)處理在很大程度上依賴于索引。只有在表很小時(shí),才會(huì)順序掃描表。系統(tǒng)會(huì)根據(jù)SQL語句中的WHERE子句判斷是否使用索引。順序掃描表會(huì)使系統(tǒng)性能受到嚴(yán)重影響。sysmaster中sysptntab表中的pf_seqscnas列顯示了所進(jìn)行的順序掃描。SET EXPLAIN命令同樣可以提供關(guān)于SQL語句如何訪問數(shù)據(jù)庫中的重要信息。
DSS環(huán)境中的應(yīng)用經(jīng)常會(huì)查詢出大量數(shù)據(jù)(低選擇性 low selecviity),甚至整張表。順序掃描對(duì)于這樣的查詢更為適合,因?yàn)榇藭r(shí)順序掃描可以利用light scan。light scan緩沖區(qū)位于共享內(nèi)存的虛擬段與駐留段無關(guān)。關(guān)于light scan,以后章節(jié)中還將詳述。
建立索引的代價(jià)
雖然索引可以很大地提高高選擇性查詢的性能,但維護(hù)這些索引是需要付出代價(jià)的。 以INSERT語句為例,在進(jìn)行插入時(shí)系統(tǒng)首先將讀取被插入表的索引以定位新記錄關(guān)鍵字的位置。然后系統(tǒng)在將新記錄寫入數(shù)據(jù)頁的同時(shí)還必須將新索引項(xiàng)寫入索引節(jié)點(diǎn)。如果導(dǎo)致索引節(jié)點(diǎn)分裂,系統(tǒng)則必須多次寫索引頁
與INSERT語句相似,DELETE語句也要求讀入整個(gè)索引以定位索引節(jié)點(diǎn)位置,并置上刪除標(biāo)志。在刪除索引時(shí)還需要處理索引節(jié)點(diǎn)合并、整理等問題。
在執(zhí)行UPDATE語句時(shí),必須首先定位并且刪除舊的關(guān)鍵字然后插入新的關(guān)鍵字。所以在UPDATE語句必須兩次讀取索引。
在實(shí)際系統(tǒng)中通常把索引的根節(jié)點(diǎn)和第一級(jí)節(jié)點(diǎn)讀入共享內(nèi)存中,但如果需要訪問更低層次的索引節(jié)點(diǎn)則必須進(jìn)行磁盤操作。
索引類型
通常建立分離索引(detached)或基于表達(dá)式的索引分片(expression based fragmented)。分離索引和分片索引可以使得索引的extent內(nèi)頁連續(xù),因而能提高性能。而對(duì)于不分片的表來說,附加索引(attached)在建立索引時(shí),索引頁和數(shù)據(jù)頁交叉存放在一起,因而會(huì)增加磁頭尋找時(shí)間。
對(duì)于中、小型表應(yīng)該建立分離索引。對(duì)于經(jīng)常訪問的大表應(yīng)建立基于表達(dá)式的分片索引,以減少索引頁的數(shù)量和提高檢索速度。索引分片不宜太多,以免表達(dá)式計(jì)算開銷過大。根據(jù)索引的大小,一般可以分為4片。索引分片不支持輪轉(zhuǎn)法(round robin)。
分離式索引與數(shù)據(jù)頁分別存放在不同的數(shù)據(jù)空間中。例如:
CREATE INDEX index1 ON TABLE table_name(col1) in idxldbs;
基于表達(dá)式的分片索引在FRAGMENT BY EXPRESSION 子句指定的數(shù)據(jù)空間中創(chuàng)建。例如:
CREATE INDEX index1 on TABLE table_name(col1) FRAGMENT BY EXPRESSION
col1>=0 and col1<=25000 in idxldbs1 col1>=25001 and col1<=50000 in idxldbs2
col1>=50001 and col1<=75000 in idxldbs3 col1>=750001 and col1<= 100000 in idxldbs4;
隱式索引
在定義約束條件時(shí)如果沒有可利用的索引,系統(tǒng)將創(chuàng)建隱式索引。用戶不能對(duì)隱式索引指定數(shù)據(jù)空間的位置、分片策略或者填充因子。隱式索引創(chuàng)建在數(shù)據(jù)庫(而非表)所在地?cái)?shù)據(jù)空間中,這給磁盤管理和性能帶來了一些影響。
用戶如果需要建立約束條件,最好能先創(chuàng)建與約束條件完全匹配的顯式索引然后用ALTER TABLE命令增加約束條件。這樣該約束條件就可以利用顯式索引而不必再建立隱式索引。例如按如下方式:
CREATE TABLE table_name( col1 INTEGER, col2 INTEGER, col3 CHAR(25), ) in tableldbs;
CREATE unique INDEX index1 ON TABLE table_name(col1) in idxldbs;
ALTER TABLE table_name ADD CONSTRAINT PRIMARYKEY(col1);
而不要按如下方式:
CREATE TABLE table_name( col1 INTEGER, col2 INTEGER, col3 CHAR(25), PRIMARY KEY (col1) ) in tableldbs;
FILLACTOR(填充因子)
對(duì)于SELECT操作,將FILLFACTOR 設(shè)為100
對(duì)于SELECT 和DELETE操作將FILLFACTOR 設(shè)為100
對(duì)于INSERT 和 UPDATE操作將FILLFACTOR設(shè)為50到70
CREATE INDEX index1 ON TABLE table_name(col1) in idx1 dbs FILLFACTOR 70;
填充因子決定了在建立索引時(shí)每一索引頁的填充度。該參數(shù)是可以改變的。參數(shù)FILLFACTOR缺省值為90。如果只是改變某個(gè)索引的設(shè)置,請(qǐng)使用CREATE INDEX的FILLFACTOR子句。
設(shè)置較大的填充因子可以使索引更緊湊、使緩沖區(qū)更有效同時(shí)也可以減少檢索記錄時(shí)讀取的頁數(shù)。對(duì)于只讀表應(yīng)將FILLFACTOR設(shè)置為100。
對(duì)于只執(zhí)行讀和操作的表,如果將FILLFACTOR設(shè)置為100,在刪除記錄時(shí)可以減少合并索引節(jié)點(diǎn)、整理索引樹的可能性。
對(duì)于有大量插入和更新操作的表,應(yīng)該將FILLFACTOR設(shè)置為50到70。由于填充因子較小,在插入和更新操作時(shí)將延遲索引節(jié)點(diǎn)(頁面)的分裂,從而提高系統(tǒng)性能。 有如下的SQL FILLFACTOR例句:
CREATE INDEX index1 ON TABLE table_name(col1) in idxldbs FILLFACTOR 70;
建立索引的步驟
建立索引必須遵循如下步驟:
確定需要建立的索引
決定索引的類型,分離索引還是分片索引。如果是分片索引,確定表達(dá)式
為每一索引確定填充因子
計(jì)算索引所需空間
決定索引數(shù)據(jù)空間在磁盤上的位置
為索引創(chuàng)建數(shù)據(jù)空間
定髓臨時(shí)數(shù)據(jù)空間大小和位置。臨時(shí)數(shù)據(jù)空間最好能分布存儲(chǔ)。
利用DBSPACETEMP 設(shè)置臨時(shí)數(shù)據(jù)空間的大小,利用onspace命令的-t選項(xiàng)創(chuàng)建臨時(shí)數(shù)據(jù)空間
設(shè)置環(huán)境變量PDQPRIORITY 和PSORT_NPROCS
創(chuàng)建相應(yīng)的配置文件。其中各選項(xiàng)的最優(yōu)設(shè)置參見并行排序和載入環(huán)境
配置參數(shù)
建立索引時(shí)參數(shù)的優(yōu)化設(shè)置與上一章載入環(huán)境中的設(shè)置相同。在此作一簡(jiǎn)單回顧:
NUMCPUVPS 設(shè)置為CPU數(shù)目
BUFFERS 設(shè)置盡量多的緩沖區(qū)。初始時(shí)應(yīng)為緩沖區(qū)分配最多至25%的內(nèi)存。?
SHMVIRTSIZE 賦予初始段最大值。最多至可用內(nèi)存的75%
CKPTINTVL 3000。由物理日志決定何時(shí)生成檢查點(diǎn)。
LRUS 一個(gè)LRU隊(duì)列對(duì)含500-700個(gè)緩沖并允許LRU隊(duì)列對(duì)最大至128
LUR_MAX_DIRTY 設(shè)置為80
LUR_MIN_dirty 設(shè)置為70 ??
RA_PAGES 設(shè)置為128,
RA_THRESHOLD 設(shè)置為120
DBSPACETEMP 設(shè)置多個(gè)大小相同的臨時(shí)數(shù)據(jù)空間分布在不同的設(shè)備上
DS_TOTAL_MEMORY 90%*SHMVIRTSIZE
DS_MAX_SCANS 待建索引表的最大分片數(shù)
下面是對(duì)環(huán)境變量的簡(jiǎn)單回顧:
PSORT_NPROCS 設(shè)置為CPU數(shù)目,最大至10
PDQPRIORITY 設(shè)置為100
數(shù)據(jù)聚集
如果經(jīng)常根據(jù)索引從表中讀取大量的數(shù)據(jù),那么最好對(duì)這些數(shù)據(jù)建立聚集。通過建立聚集可以減少讀取頁的數(shù)量,縮短檢索時(shí)間,并可以充分利用預(yù)讀功能順序掃描數(shù)據(jù)。
數(shù)據(jù)的聚集通過創(chuàng)建聚集索引(clustered index)完成。利用ALTER INDEX ...TO CLUSTER 語句可以將原有索引改為聚集索引,原有索引中的數(shù)據(jù)記錄順序?qū)⒆髦嘏?。如果直接?chuàng)建聚集索引,系統(tǒng)也會(huì)將數(shù)據(jù)記錄排序。請(qǐng)注意,在ATLTER INDEX ...TO CLUSTER 和CREATE CLUSTER INDEX 語句執(zhí)行后,系統(tǒng)將建立新表并刪除舊表。所以必須有足夠的空間來容納新舊兩張表。
如果可能,在載入數(shù)據(jù)前先對(duì)其按索引順序排序,這樣建立索引時(shí)不必設(shè)置CLUSTER子句,從而不必對(duì)數(shù)據(jù)進(jìn)行聚集操作,避免建新表刪舊表過程的開銷。