甲骨論2012版oracle視頻教程-相克軍老師_第1頁(yè)
甲骨論2012版oracle視頻教程-相克軍老師_第2頁(yè)
甲骨論2012版oracle視頻教程-相克軍老師_第3頁(yè)
甲骨論2012版oracle視頻教程-相克軍老師_第4頁(yè)
甲骨論2012版oracle視頻教程-相克軍老師_第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余91頁(yè)可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

分區(qū)(partitioning)最早在Oracle8.0中引入,這個(gè)過程是將一個(gè)表或索引物理地分解為多個(gè)更小、更可管理的部分。對(duì)索引或表進(jìn)行分區(qū)時(shí)可能發(fā)生3種情況:使用這些分區(qū)表的應(yīng)用可能運(yùn)行得更慢;可能運(yùn)行得更快;有可能沒有任何變化。調(diào)高可用性可用性的提高源自于每個(gè)分區(qū)的獨(dú)立性。對(duì)象中一個(gè)分區(qū)的可用性(或不可用)并不意味著對(duì)象本身是不可用的。優(yōu)化器知道有這種分區(qū)機(jī)制,會(huì)相應(yīng)地從查詢計(jì)劃中去除未引用的分區(qū)。在一個(gè)大對(duì)象中如果一個(gè)分區(qū)不可用,你的查詢可以消除這個(gè)分區(qū)而不予考慮,這樣Oracle就能成功地處理這個(gè)查詢。1、如果查詢必須涉及這個(gè)分區(qū),那么查詢報(bào)錯(cuò)2、如果查詢不涉及這個(gè)分區(qū),那么可以正常查詢別的分區(qū)數(shù)據(jù)的“擺放”有些隨機(jī)。通過使用散列分區(qū),我們讓Oracle隨機(jī)地(很可能均勻地)將數(shù)據(jù)分布到多個(gè)分區(qū)上。我們無法控制數(shù)據(jù)要分布到哪個(gè)分區(qū)上;Oracle會(huì)根據(jù)生成的散列鍵值來確定。模擬一個(gè)分區(qū)故障。減少管理負(fù)擔(dān)例如,假設(shè)數(shù)據(jù)庫(kù)中有一個(gè)10GB的索引。如果需要重建這個(gè)索引,而該索引未分區(qū),你就必須將整個(gè)10GB的索引作為一個(gè)工作單元來重建。盡管可以在線地重建索引,但是要完全重建完整的10GB索引,還是需要占用大量的資源。如果將索引本身劃分為10個(gè)1GB的分區(qū),各個(gè)索引的重建也更快(可能是原來的10倍)。你可能只需要重建全部聚集索引的10%,例如,只是“最新”的數(shù)據(jù)(活動(dòng)數(shù)據(jù))需要重組,而所有“較舊”的數(shù)據(jù)(相當(dāng)靜態(tài))不受影響。你發(fā)現(xiàn)表中50%的行都是“移植”行,可能想進(jìn)行修正。建立一個(gè)分區(qū)表將有利于這個(gè)操作。為了“修正”移植行,你往往必須重建對(duì)象,在這種情況下,就是要重建一個(gè)表。如果有一個(gè)100GB的表,就需要在一個(gè)非常大的“塊”(chunk)上連續(xù)地使用ALTERTABLEMOVE來執(zhí)行這個(gè)操作。另一方面,如果你有25個(gè)分區(qū),每個(gè)分區(qū)的大小為4GB,就可以一個(gè)接一個(gè)地重建各個(gè)分區(qū)。對(duì)于一個(gè)未分區(qū)對(duì)象所能做的工作,分區(qū)對(duì)象中的單個(gè)分區(qū)幾乎都能做到。你甚至可能發(fā)現(xiàn),移植行都集中在一個(gè)很小的分區(qū)子集中,因此,可以只重建一兩個(gè)分區(qū),而不是重建整個(gè)表。BIG_TABLE1和BIG_TABLE2都是從BIG_TABLE的一個(gè)10,000,000行的實(shí)例創(chuàng)建的。BIG_TABLE1是一個(gè)常規(guī)的未分區(qū)表,而BIG_TABLE2是一個(gè)散列分區(qū)表,有8個(gè)分區(qū)。createtablebig_table1(ID,OWNER,OBJECT_NAME,SUBOBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE,CREATED,LAST_DDL_TIME,TIMESTAMP,STATUS,TEMPORARY,GENERATED,SECONDARY)tablespacebig1asselectID,OWNER,OBJECT_NAME,SUBOBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE,CREATED,LAST_DDL_TIME,TIMESTAMP,STATUS,TEMPORARY,GENERATED,SECONDARYfrombig_table.big_table;createtablebig_table2(ID,OWNER,OBJECT_NAME,SUBOBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE,CREATED,LAST_DDL_TIME,TIMESTAMP,STATUS,TEMPORARY,GENERATED,SECONDARY)partitionbyhash(id)(partitionpart_1tablespacebig2,partitionpart_2tablespacebig2,partitionpart_3tablespacebig2,partitionpart_4tablespacebig2,partitionpart_5tablespacebig2,partitionpart_6tablespacebig2,partitionpart_7tablespacebig2,partitionpart_8tablespacebig2)asselectID,OWNER,OBJECT_NAME,SUBOBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE,CREATED,LAST_DDL_TIME,TIMESTAMP,STATUS,TEMPORARY,GENERATED,SECONDARYfrombig_table.big_table;每個(gè)表都在自己的表空間中,所以我們可以很容易地查詢數(shù)據(jù)字典,來查看每個(gè)表空間中已分配的空間和空閑空間:selectb.tablespace_name,mbytes_alloc,mbytes_freefrom(selectround(sum(bytes)/1024/1024)mbytes_free,tablespace_namefromdba_free_spacegroupbytablespace_name)a,(selectround(sum(bytes)/1024/1024)mbytes_alloc,tablespace_namefromdba_data_filesgroupbytablespace_name)bwherea.tablespace_name(+)=b.tablespace_nameandb.tablespace_namein('BIG1','BIG2');TABLESPACE MBYTES_ALLOC MBYTES_FREE---------- ------------ -----------BIG1 1496 344BIG2 1496 344ORA10GR1>altertablebig_table1move;altertablebig_table1move*ERRORatline1:ORA-01652:unabletoextendtempsegmentby1024intablespaceBIG1失敗了,BIG1表空間中要有足夠的空閑空間來放下BIG_TABLE1的完整副本,同時(shí)它的原副本仍然保留,簡(jiǎn)單地說,我們需要一個(gè)很短的時(shí)間內(nèi)有大約兩倍的存儲(chǔ)空間(可能多一點(diǎn),也可能少一點(diǎn),這取決于重建后表的大小)。粗略的認(rèn)為,這個(gè)表空間至少需要一倍于這個(gè)表的空閑空間。對(duì)BIG_TABLE2執(zhí)行同樣的操作:ORA10GR1>altertablebig_table2

move;altertablebig_table2move*ERRORatline1:ORA-14511:cannotperformoperationonapartitionedobject 無法對(duì)這個(gè)“表”執(zhí)行MOVE操作;我們必須在表的各個(gè)分區(qū)上執(zhí)行這個(gè)操作。可以逐個(gè)地移動(dòng)(相應(yīng)地重建和重組)各個(gè)分區(qū):ORA10GR1>altertablebig_table2movepartitionpart_1;Tablealtered.ORA10GR1>altertablebig_table2movepartitionpart_2;Tablealtered.ORA10GR1>altertablebig_table2movepartitionpart_3;Tablealtered.ORA10GR1>altertablebig_table2movepartitionpart_4;Tablealtered.ORA10GR1>altertablebig_table2movepartitionpart_5;Tablealtered.ORA10GR1>altertablebig_table2movepartitionpart_6;Tablealtered.ORA10GR1>altertablebig_table2movepartitionpart_7;Tablealtered.ORA10GR1>altertablebig_table2movepartitionpart_8;Tablealtered.

我們需要的臨時(shí)資源將顯著減少。不僅如此,如果在移動(dòng)到PART_4后但在PART_5完成“移動(dòng)”之前系統(tǒng)失敗了(例如,掉電),我們并不會(huì)丟失以前所做的所有工作,這與執(zhí)行一個(gè)MOVE語句的情況不同。前4個(gè)分區(qū)仍是“移動(dòng)”后的狀態(tài),等系統(tǒng)恢復(fù)時(shí),我們可以從分區(qū)PART_5繼續(xù)處理。ORA10GR1>beginforxin(selectpartition_namefromuser_tab_partitionswheretable_name='BIG_TABLE2')loopexecuteimmediate'altertablebig_table2movepartition'||x.partition_name;endloop;end;使用上面的腳本可以實(shí)現(xiàn)。改善語句性能分區(qū)最后一個(gè)總的(潛在)好處體現(xiàn)在改進(jìn)語句(SELECT、INSERT、UPDATE、DELETE、MERGE)的性能方面。并行DML修改數(shù)據(jù)庫(kù)中數(shù)據(jù)的語句有可能會(huì)執(zhí)行并行DML(parallelDML,PDML)。采用PDML時(shí),Oracle使用多個(gè)線程或進(jìn)程來執(zhí)行INSERT、UPDATE或DELETE,而不是執(zhí)行一個(gè)串行進(jìn)程。在一個(gè)有充足I/O帶寬的多CPU主機(jī)上,對(duì)于大規(guī)模的DML操作,速度的提升可能相當(dāng)顯著。在Oracle9i以前的版本中,PDML要求必須分區(qū)。如果你的表沒有分區(qū),在先前的版本中就不能并行地執(zhí)行這些操作。如果表確實(shí)已經(jīng)分區(qū),Oracle會(huì)根據(jù)對(duì)象所有的物理分區(qū)數(shù)為對(duì)象指定一個(gè)最大并行度。從很大程度上講,在Oracle9i及以后版本中這個(gè)限制已經(jīng)放松,只有一個(gè)突出的例外;如果希望在一個(gè)表上執(zhí)行PDML,而且這個(gè)表的一個(gè)LOB列上有一個(gè)位圖索引,要并行執(zhí)行操作就必須對(duì)這個(gè)表分區(qū);另外并行度就限制為分區(qū)數(shù)。不過,總的說來,使用PDML并不一定要求進(jìn)行分區(qū)。查詢性能在只讀查詢(SELECT語句)的性能方面,分區(qū)對(duì)兩類特殊操作起作用:1、分區(qū)消除(partitionelimination):處理查詢時(shí)不考慮某些數(shù)據(jù)分區(qū)。我們已經(jīng)看到了一個(gè)分區(qū)消除的例子。2、并行操作(paralleloperation):并行全表掃描和并行索引區(qū)間掃描就是這種操作的例子。OLTP系統(tǒng)事實(shí)上在一個(gè)OLTP系統(tǒng)中,查詢已經(jīng)有以下特點(diǎn):即索引訪問相當(dāng)快,因此,分區(qū)不會(huì)讓索引訪問的速度有太大的提高(甚至根本沒有任何提高)。這并不是說要絕對(duì)避免在OLTP系統(tǒng)中使用分區(qū);而只是說不要指望通過分區(qū)來提供大幅的性能提升。盡管有效情況下分區(qū)能夠改善查詢的性能,但是這些情況在大多數(shù)OLTP應(yīng)用中并不成立。不過在OLTP系統(tǒng)中,你還是可以得到另外兩個(gè)可能的好處:減輕管理負(fù)擔(dān)以及有更高的可用性。有分區(qū)的OLTP系統(tǒng)確實(shí)也有可能得到效率提示。例如,可以用分區(qū)來減少競(jìng)爭(zhēng),從而提高并發(fā)度。至于并行操作,你可能不希望在一個(gè)OLTP系統(tǒng)中執(zhí)行并行查詢。你會(huì)慎用并行操作,而是交由DBA來完成重建、創(chuàng)建索引、收集統(tǒng)計(jì)信息等工作。數(shù)據(jù)倉(cāng)庫(kù)系統(tǒng)處理許多查詢時(shí)都要求執(zhí)行一個(gè)全表掃描,但是最后卻發(fā)現(xiàn),一方面必須掃描數(shù)百萬條記錄,但另一方面其中大多數(shù)記錄并不適用于我們的查詢。如果使用一種明智的分區(qū)機(jī)制,就可以實(shí)現(xiàn)消除分區(qū),這樣在查詢某個(gè)給定的數(shù)據(jù)時(shí),就可以只對(duì)這個(gè)數(shù)據(jù)進(jìn)行全面掃描。這在所有可能的解決方案中是最佳的選擇。在一個(gè)數(shù)據(jù)倉(cāng)庫(kù)/決策支持環(huán)境中,會(huì)頻繁地使用并行查詢。因此,諸如并行索引區(qū)間掃描或并行快速全面索引掃描等操作對(duì)我們很有好處。表分區(qū)機(jī)制目前Oracle中有4種對(duì)表分區(qū)的方法:1、區(qū)間分區(qū):通過數(shù)據(jù)范圍進(jìn)行分區(qū)。例如,時(shí)間戳在Jan-2005內(nèi)的所有記錄都存儲(chǔ)在分區(qū)1中,時(shí)間戳在Feb-2005內(nèi)的所有記錄都存儲(chǔ)在分區(qū)2中,依此類推。這可能是Oracle中最常用的分區(qū)機(jī)制。2、散列分區(qū):這是指在一個(gè)列(或多個(gè)列)上應(yīng)用一個(gè)散列函數(shù),行會(huì)按這個(gè)散列值放在某個(gè)分區(qū)中。3、列表分區(qū):指定一個(gè)離散值集,來確定應(yīng)當(dāng)存儲(chǔ)在一起的數(shù)據(jù)。例如,可以指定STATUS列值在(’A’,’M’,’Z’)中的行放在分區(qū)1中,STATUS值在(‘D’,’P’,’Q’)中的行放在分區(qū)2中,依此類推。4、組合分區(qū):這是區(qū)間分區(qū)和散列分區(qū)的一種組合,或者是區(qū)間分區(qū)與列表分區(qū)的組合。通過組合分區(qū),你可以先對(duì)某些數(shù)據(jù)應(yīng)用區(qū)間分區(qū),再在區(qū)間中根據(jù)散列或列表來選擇最后的分區(qū)。區(qū)間分區(qū)ORA10GR1>CREATETABLErange_example(range_key_columndate,datavarchar2(20))PARTITIONBYRANGE(range_key_column)(PARTITIONpart_1VALUESLESSTHAN(to_date('01/01/2005','dd/mm/yyyy')),PARTITIONpart_2VALUESLESSTHAN(to_date('01/01/2006','dd/mm/yyyy'));

我們?cè)诜秶謪^(qū)的時(shí)候,要注意范圍分區(qū)的值的情況。ORA10GR1>CREATETABLErange_example(range_key_columndate,datavarchar2(20))PARTITIONBYRANGE(range_key_column)(PARTITIONpart_1VALUESLESSTHAN(to_date('01/01/2005','dd/mm/yyyy')),PARTITIONpart_2VALUESLESSTHAN(to_date('01/01/2006','dd/mm/yyyy'))PARTITIONpart_3VALUESLESSTHAN(MAXVALUE);向這個(gè)表插入一個(gè)行時(shí),這一行肯定會(huì)放入三個(gè)分區(qū)中的某一個(gè)分區(qū)中,而不會(huì)再拒絕任何行,因?yàn)榉謪^(qū)PART_3可以接受不能放在PART_1或PART_2中的任何RANG_KEY_COLUMN值(即使RANGE_KEY_COLUMN值為null,也會(huì)插入到這個(gè)新分區(qū)中)。散列分區(qū)對(duì)一個(gè)表執(zhí)行散列分區(qū)(hashpartitioning)時(shí),Oracle會(huì)對(duì)分區(qū)鍵應(yīng)用一個(gè)散列函數(shù),以此確定數(shù)據(jù)應(yīng)當(dāng)放在N個(gè)分區(qū)中的哪一個(gè)分區(qū)中。Oracle建議N是2的一個(gè)冪(2、4、8、16等),從而得到最佳的總體分布。散列分區(qū)設(shè)計(jì)為能使數(shù)據(jù)很好地分布在多個(gè)不同設(shè)備(磁盤)上,為表選擇的散列鍵應(yīng)當(dāng)是惟一的一個(gè)列或一組列,或者至少有足夠多的相異值,以便行能在多個(gè)分區(qū)上很好地(均勻地)分布。如果你選擇一個(gè)只有4個(gè)相異值的列,并使用兩個(gè)分區(qū),那么最后可能把所有行都散列到同一個(gè)分區(qū)上,這就有悖于分區(qū)的最初目標(biāo)!ORA10G>CREATETABLEhash_example(hash_key_columndate,datavarchar2(20))PARTITIONBYHASH(hash_key_column)(partitionpart_1tablespacep1,partitionpart_2tablespacep2);1、如果使用散列分區(qū),你將無從控制一行最終會(huì)放在哪個(gè)分區(qū)中。Oracle會(huì)應(yīng)用散列函數(shù),并根據(jù)散列的結(jié)果來確定行會(huì)放在哪里。2、如果改變散列分區(qū)的個(gè)數(shù),數(shù)據(jù)會(huì)在所有分區(qū)中重新分布(向一個(gè)散列分區(qū)表增加或刪除一個(gè)分區(qū)時(shí),將導(dǎo)致所有數(shù)據(jù)都重寫,因?yàn)楝F(xiàn)在每一行可能屬于一個(gè)不同的分區(qū))。3、分區(qū)數(shù)應(yīng)該是2的冪如果分區(qū)數(shù)是2的冪,那么分區(qū)將會(huì)均勻分布,如果不是2的冪,那么分區(qū)將會(huì)不均勻分布。我們顯然希望得到均勻分布的分區(qū)。列表分區(qū)列表分區(qū)(listpartitioning)是Oracle9iRelease1的一個(gè)新特性。它提供了這樣一種功能,可以根據(jù)離散的值列表來指定一行位于哪個(gè)分區(qū)。ORA10G>createtablelist_example(state_cdvarchar2(2),datavarchar2(20))partitionbylist(state_cd)(partitionpart_1values('ME','NH','VT','MA'),partitionpart_2values('CT','RI','NY'));1、如果我們想插入列表分區(qū)中未指定的一個(gè)值,Oracle會(huì)向客戶應(yīng)用返回一個(gè)合適的錯(cuò)誤。ORA10G>insertintolist_examplevalues('VA','data');insertintolist_examplevalues('VA','data')*ERRORatline1:ORA-14400:insertedpartitionkeydoesnotmaptoanypartition ORA10G>altertablelist_exampleaddpartitionpart_3values(DEFAULT);ORA10G>insertintolist_examplevalues('VA','data');1rowcreated. 2、關(guān)于DEFAULT的使用,有一點(diǎn)要注意:一旦列表分區(qū)表有一個(gè)DEFAULT分區(qū),就不能再向這個(gè)表中增加更多的分區(qū)了。此時(shí)必須刪除DEFAULT分區(qū),然后增加PART_4,再加回DEFAULT分區(qū)。組合分區(qū)在組合分區(qū)中,頂層分區(qū)機(jī)制總是區(qū)間分區(qū)。第二級(jí)分區(qū)機(jī)制可能是列表分區(qū)或散列分區(qū)(在Oracle9iRelease1及以前的版本中,只支持散列子分區(qū),而沒有列表分區(qū))。使用組合分區(qū)時(shí),并沒有分區(qū)段,而只有子分區(qū)段。分區(qū)本身并沒有段(這就類似于分區(qū)表沒有段)。數(shù)據(jù)物理的存儲(chǔ)在子分區(qū)段上,分區(qū)成為一個(gè)邏輯容器,或者是一個(gè)指向?qū)嶋H子分區(qū)的容器。ORA10G>CREATETABLEcomposite_example(range_key_columndate,hash_key_columnint,datavarchar2(20))PARTITIONBYRANGE(range_key_column)subpartitionbyhash(hash_key_column)subpartitions2(PARTITIONpart_1VALUESLESSTHAN(to_date('01/01/2005','dd/mm/yyyy'))(subpartitionpart_1_sub_1,subpartitionpart_1_sub_2),PARTITIONpart_2VALUESLESSTHAN(to_date('01/01/2006','dd/mm/yyyy'))(subpartitionpart_2_sub_1,subpartitionpart_2_sub_2);在區(qū)間-散列組合分區(qū)中,Oracle首先會(huì)應(yīng)用區(qū)間分區(qū)規(guī)則,得出數(shù)據(jù)屬于哪個(gè)區(qū)間。然后再應(yīng)用散列函數(shù),來確定數(shù)據(jù)最后要放在哪個(gè)物理分區(qū)中。ORA10G>CREATETABLEcomposite_range_list_example(range_key_columndate,code_key_columnint,datavarchar2(20))PARTITIONBYRANGE(range_key_column)subpartitionbylist(code_key_column)(PARTITIONpart_1VALUESLESSTHAN(to_date('01/01/2005','dd/mm/yyyy'))(subpartitionpart_1_sub_1values(1,3,5,7),subpartitionpart_1_sub_2values(2,4,6,8)),PARTITIONpart_2VALUESLESSTHAN(to_date('01/01/2006','dd/mm/yyyy'))(subpartitionpart_2_sub_1values(1,3),subpartitionpart_2_sub_2values(5,7),subpartitionpart_2_sub_3values(2,4,6,8));每個(gè)分區(qū)的子分區(qū)的數(shù)目是不一樣的。如果用于確定分區(qū)的列有修改會(huì)發(fā)生什么。需要考慮兩種情況:1、修改不會(huì)導(dǎo)致使用一個(gè)不同的分區(qū);行仍屬于原來的分區(qū)。這在所有情況下都得到支持。2、修改會(huì)導(dǎo)致行跨分區(qū)移動(dòng)。只有當(dāng)表啟用了行移動(dòng)時(shí)才支持這種情況;否則,會(huì)產(chǎn)生一個(gè)錯(cuò)誤。ORA10G>insertintorange_example(range_key_column,data)values(to_date('15-dec-200400:00:00','dd-mon-yyyyhh24:mi:ss'),'applicationdata...');ORA10G>insertintorange_example(range_key_column,data)values(to_date('01-jan-200500:00:00','dd-mon-yyyyhh24:mi:ss')-1/24/60/60,'applicationdata...');ORA10G>select*fromrange_examplepartition(part_1);RANGE_KEY DATA--------- --------------------15-DEC-04 applicationdata...31-DEC-04 applicationdata...取其中一行,并更新其RANGE_KEY_COLUMN值,不過更新后它還能放在PART_1中:ORA10G>updaterange_examplesetrange_key_column=trunc(range_key_column)whererange_key_column=to_date('31-dec-200423:59:59','dd-mon-yyyyhh24:mi:ss');成功!再把RANGE_KEY_COLUMN更新為另一個(gè)值,但這次更新后的值將導(dǎo)致它屬于分區(qū)PART_2:ORA10G>updaterange_examplesetrange_key_column=to_date('02-jan-2005','dd-mon-yyyy')whererange_key_column=to_date('31-dec-2004','dd-mon-yyyy');updaterange_example*ERRORatline1:ORA-14402:updatingpartitionkeycolumnwouldcauseapartitionchange 在Oracle8i及以后的版本中,可以在這個(gè)表上啟用行移動(dòng)(rowmovement),以允許從一個(gè)分區(qū)移動(dòng)到另一個(gè)分區(qū)。行的ROWID會(huì)由于更新而改變:ORA10G>selectrowidfromrange_examplewhererange_key_column=to_date('31-dec-2004','dd-mon-yyyy');ROWID------------------AAARmfAAKAAAI+aAABORA10G>altertablerange_exampleenablerowmovement; ORA10G>updaterange_examplesetrange_key_column=to_date('02-jan-2005','dd-mon-yyyy')whererange_key_column=to_date('31-dec-2004','dd-mon-yyyy');ORA10G>selectrowidfromrange_examplewhererange_key_column=to_date('02-jan-2005','dd-mon-yyyy');ROWID------------------AAARmgAAKAAAI+iAAC在其他一些情況下,ROWID也有可能因?yàn)楦露淖儭?、更新IOT的主鍵可能導(dǎo)致ROWID改變,該行的通用ROWID(UROWID)也會(huì)改變。2、Oracle10g的FLASHBACKTABLE命令可能改變行的ROWID3、Oracle10g的ALTERTABLESHRINK命令也可能使行的ROWID改變。1、執(zhí)行行移動(dòng)時(shí),實(shí)際上在內(nèi)部就好像先刪除了這一行,然后再將其重新插入。這會(huì)更新這個(gè)表上的索引,刪除舊的索引條目,再插入一個(gè)新條目。2、會(huì)完成DELETE再加一個(gè)INSERT的相應(yīng)物理工作。3、盡管在此執(zhí)行了行的物理刪除和插入,在Oracle看來卻還是一個(gè)更新,因此,不會(huì)導(dǎo)致INSERT和DELETE觸發(fā)器觸發(fā),只有UPDATE觸發(fā)器會(huì)觸發(fā)。4、行移動(dòng)的開銷比正常的UPDATE昂貴得多。如果構(gòu)建的系統(tǒng)會(huì)頻繁修改分區(qū)鍵,而且這種修改會(huì)導(dǎo)致分區(qū)移動(dòng),這實(shí)在是一個(gè)糟糕的設(shè)計(jì)決策。索引分區(qū)索引與表類似,也可以分區(qū)。對(duì)索引進(jìn)行分區(qū)有兩種可能的方法:1、隨表對(duì)索引完成相應(yīng)的分區(qū):這也稱為局部分區(qū)索引(locallypertitionedindex)。每個(gè)表分區(qū)都有一個(gè)索引分區(qū),而且只索引該表分區(qū)。一個(gè)給定索引分區(qū)中的所有條目都指向一個(gè)表分區(qū),表分區(qū)中的所有行都表示在一個(gè)索引分區(qū)中。2、按區(qū)間對(duì)索引分區(qū):這也稱為全局分區(qū)索引(globallypartitionedindex)。在此,索引按區(qū)間分區(qū)(或者在Oracle10g中該可以按散列分區(qū)),一個(gè)索引分區(qū)可能指向任何(和所有)表分區(qū)。對(duì)于全局分區(qū)索引,要注意實(shí)際上索引分區(qū)數(shù)可能不同于表分區(qū)數(shù)。由于全局索引只按區(qū)間或散列分區(qū),如果希望有一個(gè)列表或組合分區(qū)索引,就必須使用局部索引。局部索引會(huì)使用底層表相同的機(jī)制分區(qū)。

注意全局索引的散列分區(qū)是Oracle10gRelease1及以后的版本中才有的新特性。在Oracle9i及以前的版本中,只能按區(qū)間進(jìn)行全局分區(qū)。分區(qū)消除行為如果查詢首先訪問索引,它是否能消除分區(qū)完全取決于查詢中的謂詞。ORA10G>CREATETABLEpartitioned_table(aint,bint,datachar(20))PARTITIONBYRANGE(a)(PARTITIONpart_1VALUESLESSTHAN(2)tablespacep1,PARTITIONpart_2VALUESLESSTHAN(3)tablespacep2);小于2的值都在分區(qū)PART_1中,小于3的值則都在分區(qū)PART_2中。創(chuàng)建一個(gè)局部前綴索引LOCAL_PREFIXED和一個(gè)局部非前綴索引LOCAL_NONPREFIXED。ORA10G>createindexlocal_prefixedonpartitioned_table(a,b)local;Indexcreated.ORA10G>createindexlocal_nonprefixedonpartitioned_table(b)local;Indexcreated.非前綴索引在其定義中沒有以A作為其前導(dǎo)列(最前列),這是這一點(diǎn)使之成為一個(gè)非前綴索引。ORA10G>insertintopartitioned_tableselectmod(rownum-1,2)+1,rownum,'x'fromall_objects;48967rowscreated.ORA10G>begindbms_stats.gather_table_stats(user,'PARTITIONED_TABLE',cascade=>TRUE);end;/PL/SQLproceduresuccessfullycompleted.向一個(gè)分區(qū)中插入一些數(shù)據(jù),并收集統(tǒng)計(jì)信息。將表空間P2離線,其中包含用于表和索引的PART_2分區(qū)ORA10G>altertablespacep2offline;Tablespacealtered. 表空間P2離線后,Oracle就無法訪問這些特定的索引分區(qū)。這就好像是我們?cè)庥隽恕敖橘|(zhì)故障”,導(dǎo)致分區(qū)不可用。現(xiàn)在我們查詢這個(gè)表,來看看不同的查詢需要哪些索引分區(qū)。第一個(gè)查詢編寫為允許使用局部前綴索引:ORA10G>select*frompartitioned_tablewherea=1andb=1;A B DATA----------

----------

--------------------1

1

x 這個(gè)查詢成功了,通過查看解釋計(jì)劃,可以看到這個(gè)查詢?yōu)槭裁茨艹晒ΑJ褂肔OCAL_PREFIXED的查詢成功了。優(yōu)化器能消除LOCAL_PREFIXED的PART_2不予考慮,因?yàn)槲覀冊(cè)诓樵冎兄付薃=1,而且在計(jì)劃中可以清楚地看到PSTART和PSTOP都等于1.局部索引的限制:1、要能夠?qū)崿F(xiàn)消除分區(qū),必須將分區(qū)鍵作為where條件ORA10G>select*frompartitioned_tablewhereb=1;ERROR:ORA-00376:file13cannotbereadatthistimeORA-01110:datafile13:'/home/ora10g/.../o1_mf_p2_1dzn8jwp_.dbf'norowsselected ORA10G>deletefromplan_table;4rowsdeleted.ORA10G>explainplanforselect*frompartitioned_tablewhereb=1;Explained.select*fromtable(dbms_xplan.display); select*frompartitioned_tablewhereb=1;沒有實(shí)現(xiàn)消除分區(qū),因此訪問所有分區(qū)。是否消除分區(qū),關(guān)鍵看的是是否使用分區(qū)鍵,和前綴索引、非前綴索引沒有關(guān)系。要使用非前綴索引,必須使用一個(gè)允許分區(qū)消除的查詢。,這樣效率才會(huì)提高。ORA10G>dropindexlocal_prefixed;Indexdropped.ORA10G>select*frompartitioned_tablewherea=1andb=1;A B DATA---------- ---------- --------------------1 1 x 非前綴索引也能實(shí)現(xiàn)消除分區(qū)。如果不能實(shí)現(xiàn)分區(qū)消除,那么oracle將會(huì)對(duì)多個(gè)分區(qū)的多個(gè)分區(qū)索引進(jìn)行掃描。不必對(duì)非前綴索引退避三舍,也不要認(rèn)為非前綴索引是主要的性能障礙。重點(diǎn)是,要盡可能保證查詢包含的謂詞允許索引分區(qū)消除。使用前綴局部索引可以保證這一點(diǎn),使用非前綴索引則不能保證。主要是因?yàn)榍熬Y索引將分區(qū)鍵作為前導(dǎo)列。如果你頻繁地用以下查詢來查詢先前的表:select...frompartitioned_tablewherea=:aandb=:b; select...frompartitioned_tablewhereb=:b; 可以考慮在(b,a)上使用一個(gè)局部非前綴索引。這個(gè)索引對(duì)于前面的兩個(gè)查詢都是有用的。(a,b)上的局部前綴索引只對(duì)第一個(gè)查詢有用。局部索引和惟一約束為了保證惟一性(這包括UNIQUE約束或PRIMARYKEY約束),如果你想使用一個(gè)局部索引來保證這個(gè)約束,那么分區(qū)鍵必須包括在約束本身中。這是局部索引的最大限制。Oracle只保證索引分區(qū)內(nèi)部的惟一性,而不能跨分區(qū)。這意味著不能一方面在一個(gè)TIMESTAMP字段上執(zhí)行區(qū)間分區(qū),而另一方面在ID上有一個(gè)主鍵(使用一個(gè)局部分區(qū)索引來保證)。Oracle會(huì)利用全局索引來保證惟一性。分區(qū)鍵建立分區(qū)以后,保證在不同的分區(qū)內(nèi),分區(qū)鍵一定是不同的。如果建立主鍵的時(shí)候,包括分區(qū)鍵,那么可以保證分區(qū)鍵不同的時(shí)候,一定在不同的分區(qū)內(nèi),分區(qū)鍵相同的時(shí)候,一定在同一個(gè)分區(qū)內(nèi)。這樣局部唯一性約束可以保證整個(gè)表的唯一性。創(chuàng)建一個(gè)區(qū)間分區(qū)表,它按一個(gè)名為L(zhǎng)OAD_TYPE的列分區(qū),卻在ID列上有一個(gè)主鍵ORA10G>CREATETABLEpartitioned(load_datedate,idint,constraintpartitioned_pkprimarykey(id))PARTITIONBYRANGE(load_date)(PARTITIONpart_1VALUESLESSTHAN(to_date('01/01/2000','dd/mm/yyyy')),PARTITIONpart_2VALUESLESSTHAN(to_date('01/01/2001','dd/mm/yyyy')));主鍵索引是一個(gè)全局索引,沒有進(jìn)行分區(qū)。系統(tǒng)想在id列上建立一個(gè)全局索引,發(fā)現(xiàn)這個(gè)列上已經(jīng)建立了索引,系統(tǒng)報(bào)錯(cuò)。如果這個(gè)列上沒有建立索引,那么主鍵就會(huì)建立成功。如果這個(gè)鍵上建立了一個(gè)全局索引,那么主鍵也會(huì)建立成功,主鍵將會(huì)使用這個(gè)索引。全局索引全局索引使用一種有別于底層表的機(jī)制進(jìn)行分區(qū)。表可以按一個(gè)TIMESTAMP列劃分為10個(gè)分區(qū),而這個(gè)表上的一個(gè)全局索引可以按REGION列劃分為5個(gè)分區(qū)。與局部索引不同,全局索引只有一類,這就是前綴全局索引(prefixedglobalindex)。如果全局索引的索引鍵未從該索引的分區(qū)鍵開始,這是不允許的。這說明,不論用什么屬性對(duì)索引分區(qū),這些屬性都必須是索引鍵的前幾列。CREATETABLEpartitioned(timestampdate,idint)PARTITIONBYRANGE(timestamp)(PARTITIONpart_1VALUESLESSTHAN(to_date('01-jan-2000','dd-mon-yyyy')),PARTITIONpart_2VALUESLESSTHAN(to_date('01-jan-2001','dd-mon-yyyy')));建立了一個(gè)分區(qū)表,分區(qū)鍵是timestamp。ORA10G>createindexpartitioned_indexonpartitioned(id)GLOBALpartitionbyrange(id)(partitionpart_1valueslessthan(1000),partitionpart_2valueslessthan(MAXVALUE));建立了全局索引以后,對(duì)全局索引進(jìn)行了分區(qū)。我們?cè)谶M(jìn)行索引搜索的時(shí)候,首先根據(jù)where

id=100,迅速的確定這個(gè)搜索落在哪個(gè)索引分區(qū)內(nèi),實(shí)現(xiàn)了索引分區(qū)的消減分區(qū)。也就是說,我們只需要搜索一個(gè)索引樹。注意,這個(gè)索引中使用了MAXVALUE。MAXVALUE不僅可以用于索引中,還可以用于任何區(qū)間分區(qū)表中。它表示區(qū)間的“無限上界”。在此前的所有例子中,我們都使用了區(qū)間的硬性上界(小于<某個(gè)值>的值)。不過,全局索引有一個(gè)需求,即最高分區(qū)(最后一個(gè)分區(qū))必須有一個(gè)值為MAXVALUE的分區(qū)上界。這可以確保底層表中的所有行都能放在這個(gè)索引中。ORA10G>altertablepartitionedaddconstraintpartitioned_pkprimarykey(id);因?yàn)樵趇d列上有一個(gè)全局索引,因此這個(gè)主鍵直接使用這個(gè)全局索引。ORA10G>dropindexpartitioned_index;dropindexpartitioned_index*ERRORatline1:ORA-02429:cannotdropindexusedforenforcementofunique/primarykey 這個(gè)表示我們建立了的索引被主鍵使用。ORA10G>createindexpartitioned_index2onpartitioned(timestamp,id)GLOBALpartitionbyrange(id)(partitionpart_1valueslessthan(1000),partitionpart_2valueslessthan(MAXVALUE))partitionbyrange(id)*ERRORatline4:ORA-14038:GLOBALpartitionedindexmustbeprefixed全局分區(qū)索引必須能夠?qū)崿F(xiàn)當(dāng)進(jìn)行where條件匹配的時(shí)候,首先能夠消減分區(qū),然后在一個(gè)分區(qū)內(nèi)實(shí)現(xiàn)索引的搜索。我們可以以timestamp進(jìn)行分區(qū),也可以以timestamp

id復(fù)合進(jìn)行分區(qū)。也就是必須使用索引的前導(dǎo)列進(jìn)行分區(qū)。數(shù)據(jù)倉(cāng)庫(kù)和全局索引原先數(shù)據(jù)倉(cāng)庫(kù)和全局索引是相當(dāng)互斥的。數(shù)據(jù)倉(cāng)庫(kù)就意味著系統(tǒng)有某些性質(zhì),如有大量的數(shù)據(jù)出入。許多數(shù)據(jù)倉(cāng)庫(kù)都實(shí)現(xiàn)了一種滑動(dòng)窗口(slidingwindow)方法來管理數(shù)據(jù),也就是說,刪除表中最舊的分區(qū),并為新加載的數(shù)據(jù)增加一個(gè)新分區(qū)。在過去(Oracle8i及以前的版本),數(shù)據(jù)倉(cāng)庫(kù)系統(tǒng)都避免使用全局索引,對(duì)此有一個(gè)很好的原因:全局索引缺乏可用性。大多數(shù)分區(qū)操作(如刪除一個(gè)舊分區(qū))都會(huì)使全局索引無效,除非重建全局索引,否則無法使用,這會(huì)嚴(yán)重地影響可用性,以前往往都是如此。滑動(dòng)窗口和索引

下面的例子實(shí)現(xiàn)了一個(gè)經(jīng)典的數(shù)據(jù)滑動(dòng)窗口。在許多實(shí)現(xiàn)中,會(huì)隨著時(shí)間的推移向倉(cāng)庫(kù)中增加數(shù)據(jù),而最舊的數(shù)據(jù)會(huì)老化。在很多時(shí)候,這個(gè)數(shù)據(jù)會(huì)按一個(gè)日期屬性進(jìn)行區(qū)間分區(qū),所以最舊的數(shù)據(jù)多存儲(chǔ)在一個(gè)分區(qū)中,新加載的數(shù)據(jù)很可能都存儲(chǔ)在一個(gè)新分區(qū)中。每月的加載過程涉及:

1、去除老數(shù)據(jù):最舊的分區(qū)要么被刪除,要么與一個(gè)空表交換(將最舊的分區(qū)變?yōu)橐粋€(gè)表),從而允許對(duì)舊數(shù)據(jù)進(jìn)行歸檔。

2、加載新數(shù)據(jù)并建立索引:將新數(shù)據(jù)加載到一個(gè)“工作”表中,建立索引并進(jìn)行驗(yàn)證。

3、關(guān)聯(lián)新數(shù)據(jù):一旦加載并處理了新數(shù)據(jù),數(shù)據(jù)所在的表會(huì)與分區(qū)表中的一個(gè)空分區(qū)交換,將表中的這些新加載的數(shù)據(jù)變成分區(qū)表中的一個(gè)分區(qū)(分區(qū)表會(huì)變得更大)。在這個(gè)例子中,我們將處理每年的數(shù)據(jù),并加載2004和2005財(cái)政年度的數(shù)據(jù)。這個(gè)表按TIMESTAMP列分區(qū),并創(chuàng)建了兩個(gè)索引,一個(gè)是ID列上的局部分區(qū)索引,另一個(gè)是TIMESTAMP列上的全局索引:ORA10G>CREATETABLEpartitioned(timestampdate,idint)PARTITIONBYRANGE(timestamp)(PARTITIONfy_2004VALUESLESSTHAN(to_date('01-jan-2005','dd-mon-yyyy')),PARTITIONfy_2005VALUESLESSTHAN(to_date('01-jan-2006','dd-mon-yyyy')));ORA10G>insertintopartitionedpartition(fy_2004)selectto_date('31-dec-2004',’dd-mon-yyyy’)-mod(rownum,360),object_idfromall_objects;ORA10G>insertintopartitionedpartition(fy_2005)selectto_date('31-dec-2005',’dd-mon-yyyy’)-mod(rownum,360),object_idfromall_objects;ORA10G>createindexpartitioned_idx_localonpartitioned(id)LOCAL/ORA10G>createindexpartitioned_idx_globalonpartitioned(timestamp)GLOBAL/數(shù)據(jù)按財(cái)政年度分區(qū),而且最后兩年的數(shù)據(jù)在線。這個(gè)表有兩個(gè)索引:一個(gè)是LOCAL索引,另一個(gè)是GLOBAL索引。現(xiàn)在正處于年末,我們想做下面的工作:

(1)刪除最舊的財(cái)政年度數(shù)據(jù)。我們不想永遠(yuǎn)地丟掉這個(gè)數(shù)據(jù),而只是希望它老化,并將其歸檔。(2)增加最新的財(cái)政年度數(shù)據(jù)。加載、轉(zhuǎn)換、建索引等工作需要一定的時(shí)間。我們想做這個(gè)工作,但是希望盡可能不影響當(dāng)前數(shù)據(jù)的可用性。第一步是為2004財(cái)政年度建立一個(gè)看上去就像分區(qū)表的空表。我們將使用這個(gè)表與分區(qū)表中的FY_2004分區(qū)交換。ORA10G>createtablefy_2004(timestampdate,idint);Tablecreated.ORA10G>createindexfy_2004_idxonfy_2004(id)Indexcreated.對(duì)要加載的新數(shù)據(jù)做同樣的工作。我們將創(chuàng)建并加載一個(gè)表,其結(jié)構(gòu)就像是現(xiàn)在的分區(qū)表。ORA10G>createtablefy_2006(timestampdate,idint);Tablecreated.ORA10G>insertintofy_2006selectto_date('31-dec-2006','dd-mon-yyyy')-mod(rownum,360),object_idfromall_objects;ORA10G>createindexfy_2006_idxonfy_2006(id)nologging; ORA10G>altertablepartitionedexchangepartitionfy_2004withtablefy_2004includingindexeswithoutvalidation/Tablealtered.ORA10G>altertablepartitioneddroppartitionfy_2004/Tablealtered.將分區(qū)交換出去,然后刪除舊的分區(qū),同時(shí)也將分區(qū)索引交換出去。ORA10G>altertablepartitionedaddpartitionfy_2006valueslessthan(to_date('01-jan-2007','dd-mon-yyyy'))Tablealtered.ORA10G>altertablepartitionedexchangepartitionfy_2006withtablefy_2006includingindexeswithoutvalidation將表交換進(jìn)來,同時(shí)包括表的索引也交換進(jìn)來。這個(gè)工作會(huì)立即完成;這是通過簡(jiǎn)單的數(shù)據(jù)字典更新實(shí)現(xiàn)的。增加空分區(qū)幾乎不需要多少時(shí)間來處理。然后,將新創(chuàng)建的空分區(qū)與滿表交換(滿表與空分區(qū)交換),這個(gè)操作也會(huì)很快完成。新數(shù)據(jù)是在線的。到此為止滑動(dòng)窗口過程幾乎不會(huì)帶來任何停機(jī)時(shí)間,但是在我們重建全局索引時(shí),需要相當(dāng)長(zhǎng)的時(shí)間才能完成。如果查詢依賴于這些索引,在此期間它們的運(yùn)行時(shí)查詢性能就會(huì)受到負(fù)面影響,可能根本不會(huì)運(yùn)行,也可能運(yùn)行時(shí)得不到索引提供的好處。所有數(shù)據(jù)都必須掃描,而且要根據(jù)數(shù)據(jù)重建整個(gè)索引。如果表的大小為數(shù)百DB,這會(huì)占用相當(dāng)多的資源。從Oracle9i開始,對(duì)于分區(qū)維護(hù)又增加了另一個(gè)選項(xiàng):可以在分區(qū)操作期間使用UPDATEGLOBALINEXES子句來維護(hù)全局索引。在你刪除一個(gè)分區(qū)、分解一個(gè)分區(qū)以及在分區(qū)上執(zhí)行任何必要的操作時(shí),Oracle會(huì)對(duì)全局索引執(zhí)行必要的修改,保證它是最新的。由于大多數(shù)分區(qū)操作都會(huì)導(dǎo)致全局索引無效,這個(gè)特征對(duì)于需要提供數(shù)據(jù)連續(xù)訪問的系統(tǒng)來說是一個(gè)大福音。你會(huì)發(fā)現(xiàn),通過犧牲分區(qū)操作的速度,可以換取100%的數(shù)據(jù)可用性(盡管分區(qū)操作的總體響應(yīng)時(shí)間會(huì)更慢)。簡(jiǎn)單地說,如果數(shù)據(jù)倉(cāng)庫(kù)不允許有停機(jī)時(shí)間,而且必須支持?jǐn)?shù)據(jù)的滑入滑出等數(shù)據(jù)倉(cāng)庫(kù)技術(shù),這個(gè)特性就再合適不過了,但是你必須了解它帶來的影響。ORA10G>altertablepartitionedexchangepartitionfy_2004withtablefy_2004includingindexeswithoutvalidationUPDATEGLOBALINDEXESORA10G>altertablepartitioneddroppartitionfy_2004UPDATEGLOBALINDEXESORA10G>altertablepartitionedaddpartitionfy_2006valueslessthan(to_date('01-jan-2007','dd-mon-yyyy'))ORA10G>altertablepartitionedexchangepartitionfy_2006withtablefy_2006includingindexeswithoutvalidationUPDATEGLOBALINDEXES這里要做一個(gè)權(quán)衡:我們要在全局索引結(jié)構(gòu)上執(zhí)行INSERT和DELETE操作的相應(yīng)邏輯操作。刪除一個(gè)分區(qū)時(shí),必須刪除可能指向該分區(qū)的所有全局索引條目。執(zhí)行表與分區(qū)的交換時(shí),必須刪除指向原數(shù)據(jù)的所有全局索引條目,再插入指向剛滑入的數(shù)據(jù)的新條目。所以ALTER命令執(zhí)行的工作量會(huì)大幅增加。下面是用runstats來測(cè)試整個(gè)的性能:execrunStats_pkg.rs_start;altertablepartitionedexchangepartitionfy_2004withtablefy_2004includingindexeswithoutvalidation;altertablepartitioneddroppartitionfy_2004;altertablepartitionedaddpartitionfy_2006valueslessthan(to_date('01-jan-2007','dd-mon-yyyy'));altertablepartitionedexchangepartitionfy_2006withtablefy_2006includingindexeswithoutvalidation;alterindexpartitioned_idx_globalrebuild;execrunStats_pkg.rs_middle;altertablepartitionedexchangepartitionfy_2005withtablefy_2005includingindexeswithoutvalidationupdateglobalindexes;altertablepartitioneddroppartitionfy_2005updateglobalindexes;altertablepartitionedaddpartitionfy_2007valueslessthan(to_date('01-jan-2008','dd-mon-yyyy'));altertablepartitionedexchangepartitionfy_2007withtablefy_2007includingindexeswithoutvalidationupdateglobalindexes;execrunStats_pkg.rs_stop;OLTP和全局索引OLTP系統(tǒng)的特點(diǎn)是會(huì)頻繁出現(xiàn)許多小的讀寫事務(wù),一般來講,在OLTP系統(tǒng)中,首要的是需要快速訪問所需的行,而且數(shù)據(jù)完整性很關(guān)鍵,另外可用性也非常重要。

在OLTP系統(tǒng)中,許多情況下全局索引很有意義。表數(shù)據(jù)可以按一個(gè)鍵(一個(gè)列鍵)分區(qū)。不過,你可能需要以多種不同的方式訪問數(shù)據(jù)。例如,可能會(huì)按表中的LOCATION來劃分EMPLOYEE數(shù)據(jù),但是還需要按以下列快速訪問EMPLOYEE數(shù)據(jù):1、DEPARTMENT:部門的地理位置很分散。部門和位置之間沒有任何關(guān)系。2、EMPLOYEE_ID:盡管員工ID能確定位置,但是你不希望必須按EMPLOYEE_ID和LOCATION搜索,因?yàn)檫@樣一來索引分區(qū)上將不能發(fā)生分區(qū)消除。而且EMPLOYEE_ID本身必然是惟一的。3、JOB_TITLE:JOB_TITLE和LOCATION之間沒有任何關(guān)系。任何LOCATION上都可以出現(xiàn)所有JOB_TITLE值。在一個(gè)數(shù)據(jù)倉(cāng)庫(kù)中,可以只使用這些鍵上的局部分區(qū)索引,并使用并行索引區(qū)間掃描來快速收集大量數(shù)據(jù)。在這些情況下不必使用索引分區(qū)消除。在OLTP系統(tǒng)中則不同,確實(shí)需要使用分區(qū)消除,并發(fā)查詢對(duì)這些系統(tǒng)不合適;我們要適當(dāng)?shù)靥峁┧饕R虼耍枰媚承┳侄紊系娜炙饕N覀円獫M足以下目標(biāo):1、快速訪問2、數(shù)據(jù)完整性3、可用性在一個(gè)OLTP系統(tǒng)中,可以通過全局索引實(shí)現(xiàn)這些目標(biāo)。我們可能不實(shí)現(xiàn)滑動(dòng)窗口,而且暫時(shí)不考慮審計(jì)。我們并不分解分區(qū)(除非有一個(gè)預(yù)定的停機(jī)時(shí)間),也不會(huì)移動(dòng)數(shù)據(jù),等等。對(duì)于數(shù)據(jù)倉(cāng)庫(kù)中執(zhí)行的操作,一般來說不會(huì)在活動(dòng)的OLTP系統(tǒng)中執(zhí)行它們。ORA10G>createtableemp(EMPNONUMBER(4)NOTNULL,ENAMEVARCHAR2(10),JOBVARCHAR2(9),MGRNUMBER(4),HIREDATEDATE,SALNUMBER(7,2),COMMNUMBER(7,2),DEPTNONUMBER(2)NOTNULL,LOCVARCHAR2(13)NOTNULL)partitionbyrange(loc)(partitionp1valueslessthan('C')tablespacep1,partitionp2valueslessthan('D')tablespacep2,partitionp3valueslessthan('N')tablespacep3,partitionp4valueslessthan('Z')tablespacep4);建立一個(gè)分區(qū)表,分區(qū)鍵是LOC。ORA10G>altertableempaddconstraintemp_pkprimarykey(empno);ORA10G>createindexemp_job_idxonemp(job)GLOBAL ORA10G>createindexemp_dept_idxonemp(deptno)GLOBAL 建立了三個(gè)全局索引。insertintoempselecte.*,d.locfromscott.empe,scott.deptdwheree.deptno=d.deptno;插入數(shù)據(jù)這里的計(jì)劃顯示出對(duì)未分區(qū)索引EMP_PK(為支持主鍵所創(chuàng)建)有一個(gè)INDEXUNIQUESCAN。然后還有一個(gè)TABLEACCESSGLOBALINDEXROWID,其PSTART和PSTOP為ROWID/ROWID,這說明從索引得到ROWID時(shí),它會(huì)準(zhǔn)確地告訴我們讀哪個(gè)表分區(qū)來得到這一行。這個(gè)訪問和未分區(qū)表效果一樣。對(duì)于INDEXRANGESCAN,可以看到類似的結(jié)果。在此使用了我們的索引,而且可以對(duì)底層數(shù)據(jù)提供高速的OLTP訪問。如果索引進(jìn)行了分區(qū),則必須是前綴索引,并保證索引分區(qū)消除;因此,這些索引也是可擴(kuò)縮的,這說明我們可以對(duì)其分區(qū),而且能觀察到類似的行為。下面來看可用性方面。在OLTP系統(tǒng)中,全局分區(qū)索引與局部分區(qū)索引有著同樣的高度可用性。通過這個(gè)案例:全局索引在訪問底層表的時(shí)候,也會(huì)利用分區(qū)表的特性。ORA10G>selectempno,job,locfromempwherejob='CLERK';selectempno,job,locfromempwherejob='CLERK'*ERRORatline1:ORA-00376:file13cannotbereadatthistimeORA-01110:datafile13:'/home/ora10g/oradata/.../o1_mf_p2_1dzn8jwp_.dbf‘所有分區(qū)中都有CLERK數(shù)據(jù),由于3個(gè)表空間離線,這一點(diǎn)確實(shí)會(huì)對(duì)我們帶來影響。這是不可避免的,除非我們?cè)贘OB上分區(qū),但是這樣一來,就會(huì)像按LOC分區(qū)查詢數(shù)據(jù)一樣出現(xiàn)同樣的問題。Oracle會(huì)“盡其所能”地為你提供數(shù)據(jù)。ORA10G>selectcount(*)fromempwherejob='CLERK';COUNT(*)----------4 如果可以由索引來回答查詢,就要避免TABLEACCESSBYROWID,數(shù)據(jù)不可用的事實(shí)并不重要。分區(qū)和性能對(duì)總體查詢性能來說,分區(qū)的影響無非有以下三種可能:1、使你的查詢更快2、根本不影響查詢的性能3、使你的查詢更慢,而且與未分區(qū)實(shí)現(xiàn)相比,會(huì)占用多出幾倍的資源在一個(gè)數(shù)據(jù)倉(cāng)庫(kù)中,如果查詢頻繁地全面掃描很大的數(shù)據(jù)表,通過消除大段的數(shù)據(jù),分區(qū)能夠?qū)@些查詢有很好的影響。通過分區(qū)消除,90%的數(shù)據(jù)都可以不考慮。你的查詢往往會(huì)運(yùn)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論