Oracle試圖自動(dòng)化系統(tǒng)配置來(lái)使并行操作的性能最大化。然而,仍然有許多手工調(diào)整的空間,我們可以調(diào)整數(shù)據(jù)庫(kù),優(yōu)化SQL并行性能。
麻山網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,麻山網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為麻山超過千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的麻山做網(wǎng)站的公司定做!
判斷并行度
合適的并行度DOP對(duì)于良好的并行性能很關(guān)鍵。Oracle會(huì)按如下方式設(shè)定DOP:
1、如果指定或請(qǐng)求了并行執(zhí)行,但是沒有指定DOP,默認(rèn)DOP會(huì)設(shè)置為該系統(tǒng)上CPU內(nèi)核數(shù)量的兩倍。對(duì)于RAC系統(tǒng),DOP值會(huì)是整個(gè)集群內(nèi)核數(shù)量的兩倍。默認(rèn)值是由配置參數(shù)“PARALLEL_ THREADS_PER_CPU”控制的。
2、對(duì)于Oracle 11g R2之后的版本,如果“ PARALLEL_DEGREE_POLICY”被設(shè)置為“AUTO”,Oracle將根據(jù)被執(zhí)行的運(yùn)行性質(zhì)和涉及對(duì)象的大小自動(dòng)調(diào)整DOP值。
3、如果“PARALLEL_ADAPTIVE_MULTI_USER”被設(shè)置為“TRUE”,Oracle將基于該系統(tǒng)的整個(gè)負(fù)載調(diào)整DOP。當(dāng)系統(tǒng)承受更重的負(fù)載時(shí),DOP值將會(huì)減少。
4、在Oracle 11g或者更高版本中,如果“PARALLEL_IO_CAP ”被設(shè)置為TRUE,Oracle將把DOP限制為IO子系統(tǒng)可以支持的值。這些IO子系統(tǒng)限制可以通過“DBMS_RESOURCE_ MANAGER.CALIBRATE_IO”存儲(chǔ)過程計(jì)算。
5、DOP可以被指定到表或者索引一級(jí),可以通過在“CREATE TABLE”,“CREATE INDEX”,“ALTER TABLE”或者“ALTER INDEX”中使用“PARALLEL ”從句來(lái)實(shí)現(xiàn)。
6、“PARALLEL ”關(guān)鍵字可以被用來(lái)指定某個(gè)查詢中指定表的DOP。
7、不管任何其它設(shè)置,DOP不能超過“PARALLEL_MAX_SERVERS”可以支持的數(shù)量。對(duì)于大部分SQL語(yǔ)句,服務(wù)器數(shù)量需要是請(qǐng)求DOP的兩倍。
正如我們可以看到的,超過優(yōu)化點(diǎn)增減DOP會(huì)導(dǎo)致進(jìn)一步性能提升的失敗。然而,超過最佳優(yōu)化限制強(qiáng)行增加DOP值會(huì)對(duì)整個(gè)系統(tǒng)性能帶來(lái)重大的負(fù)面影響。盡管被并行化的SQL可能不會(huì)隨著DOP的增加而降低,但是該系統(tǒng)的負(fù)載會(huì)持續(xù)增加,而且會(huì)引起其它并發(fā)運(yùn)行的SQL要遭受響應(yīng)時(shí)間降低的影響。
當(dāng)我們達(dá)到最優(yōu)DOP點(diǎn)時(shí)(該系統(tǒng)中的值大約是8),查詢時(shí)間的減少變的平緩了。然而,其它會(huì)話在等待CPU可用上花費(fèi)的時(shí)間會(huì)持續(xù)增長(zhǎng)。其它等待訪問CPU的會(huì)話將需要繼續(xù)等待,這會(huì)導(dǎo)致響應(yīng)時(shí)間變慢。
建索引時(shí),我們?yōu)榱私ㄋ饕?,?huì)加上并行,加上并行之后,此列索引就會(huì)是并行了。訪問有并行度的索引時(shí),CBO可能可能會(huì)考慮并行執(zhí)行,這可能會(huì)引發(fā)一些問題,如在服務(wù)器資源緊張的時(shí)候用并行會(huì)引起更加嚴(yán)重的爭(zhēng)用。當(dāng)使用并行后,需要把并行度改回來(lái)。\x0d\x0aSQL drop table test purge;\x0d\x0aSQL create table test as select * from dba_objects;\x0d\x0aSQL create index ind_t_object_id on test(object_id) parallel 4 ;\x0d\x0aSQL select s.degree\x0d\x0afrom dba_indexes s\x0d\x0awhere s.index_name = upper('ind_t_object_id');\x0d\x0aDEGREE\x0d\x0a----------------------------------------\x0d\x0a4\x0d\x0a\x0d\x0aSQL alter index ind_t_object_id noparallel;\x0d\x0a\x0d\x0aSQL select s.degree\x0d\x0afrom dba_indexes s\x0d\x0awhere s.index_name = upper('ind_t_object_id');\x0d\x0aDEGREE\x0d\x0a----------------------------------------\x0d\x0a1
一般表數(shù)據(jù)量比較大(超過100萬(wàn))時(shí),可以使用parallel強(qiáng)制啟動(dòng)并行度來(lái)提升查詢速度
用法:/*+parallel(table_short_name,cash_number)*/
可以加到insert、delete、update、select的后面來(lái)使用
比如:select /*+paralle(t,32)*/ from table t;?table_short_name使用別名,Parallel后面的數(shù)字,越大,執(zhí)行效率越高,一般用8,10,12,16,32。不過,數(shù)值越大,占用的資源也會(huì)相對(duì)增大。如果在查詢where后的條件有加索引查詢效率會(huì)大大提高。
并行概念
并行執(zhí)行(parallel execution)是Oracle企業(yè)版才有的特性(標(biāo)準(zhǔn)版中沒有這個(gè)特性),指能夠?qū)⒁粋€(gè)大型串行任務(wù)(任何DML,或者一般的DDL)物理地劃分為多個(gè)較小的部分,這些較小的部分可以同時(shí)得到處理。
并行包括:
并行查詢:這是指能使用多個(gè)操作系統(tǒng)進(jìn)程或線程來(lái)執(zhí)行一個(gè)查詢。Oracle會(huì)發(fā)現(xiàn)能并行執(zhí)行的操作(如全表掃描或大規(guī)模排序),并創(chuàng)建一個(gè)查詢計(jì)劃來(lái)實(shí)現(xiàn))。
并行DML(PDML):這在本質(zhì)上與并行查詢很相似,但是PDML主要是使用并行處理來(lái)執(zhí)行修改(INSERT、UPDATE、DELETE和MERGE)。
并行DDL:并行DDL是指Oracle能并行地執(zhí)行大規(guī)模的DDL操作。例如,索引重建、創(chuàng)建一個(gè)新索引、數(shù)據(jù)加載以及大表的重組等都可以使用并行處理。
并行恢復(fù):這是指數(shù)據(jù)庫(kù)能并行地執(zhí)行實(shí)例(甚至介質(zhì))恢復(fù),以減少?gòu)墓收匣謴?fù)所需的時(shí)間。
過程并行化:這是指能并行地運(yùn)行所開發(fā)的代碼。
何時(shí)使用并行
在應(yīng)用并行執(zhí)行之前,需要保證以下兩點(diǎn)成立:
必須有一個(gè)非常大的任務(wù),如對(duì)50GB數(shù)據(jù)進(jìn)行全面掃描。
必須有足夠的可用資源(CPU、I/O、內(nèi)存)。在并行全面掃描50GB數(shù)據(jù)之前,你要確保有足夠的空閑CPU(以容納并行進(jìn)程),還要有足夠的I/O通道。
如果只有一個(gè)小任務(wù)(通常OLTP系統(tǒng)中執(zhí)行的查詢就是這種典型的小任務(wù)),或者你的可用資源不足(這也是OLTP系統(tǒng)中很典型的情況),其中CPU和I/O資源通常已經(jīng)得到最大限度的使用,那就根本不用考慮并行執(zhí)行。
如果一個(gè)任務(wù)只需要幾秒(或更短時(shí)間)就能串行地完成,引入并行執(zhí)行后,相關(guān)的管理開銷可能會(huì)讓整個(gè)過程花費(fèi)更長(zhǎng)的時(shí)間。
舉例如,寫一頁(yè)文檔若12個(gè)人來(lái)寫,需要開會(huì)分段等,可能并不如一個(gè)人來(lái)寫更快。而如果寫1200頁(yè),12個(gè)人寫需要的時(shí)間只為原來(lái)的1/12,就算分配任務(wù)可能也就1/12,還是比一個(gè)人寫要快多了。
并行查詢
并行查詢?cè)试S將一個(gè)SQL SELECT語(yǔ)句劃分為多個(gè)較小的查詢,每個(gè)部分的查詢并發(fā)地運(yùn)行,然后會(huì)將各個(gè)部分的結(jié)果組合起來(lái),提供最終的答案。
在并行進(jìn)程和掃描文件之間并不存在1對(duì)1映射,可以多個(gè)進(jìn)程掃描同一個(gè)文件。
各個(gè)并行進(jìn)程可稱為并行執(zhí)行服務(wù)器(parallel execution server),有時(shí)也稱為并行查詢(parallel
query,PQ)從屬進(jìn)程。各個(gè)并行執(zhí)行服務(wù)器都是單獨(dú)的會(huì)話,就像是專業(yè)服務(wù)器進(jìn)程一樣連接數(shù)據(jù)庫(kù)。每個(gè)并行執(zhí)行服務(wù)器分別負(fù)責(zé)掃描表中一個(gè)部分(各
個(gè)部分都不重疊),匯總其結(jié)果子集,將其輸出發(fā)回給協(xié)調(diào)服務(wù)器(即原始會(huì)話的服務(wù)器進(jìn)程),它再將這些子結(jié)果匯總為最終答案。
在默認(rèn)情況下,Oracle是不啟用并行查詢的。啟用并行查詢有多種方法,可以直接在查詢中使用一個(gè)提示,或者修改表要求考慮并行執(zhí)行路徑等。
【并行查詢方法】
1)暗示hints式,臨時(shí)有效
select /*+parallel(table_name num)*/ count(*) from table_name;
多表關(guān)聯(lián)時(shí)多表并行:
select /*+parallel(table_name1,num1) parallel(table_name2,num2)*/ count(*) from table_name1, table_name2;
2)alter table對(duì)象式,長(zhǎng)期有效
alter table table_name parallel num;
3)alter session會(huì)話式,會(huì)話生命周期有效
alter session force parallel query parallel num;
4)并行DDL式,會(huì)話生命周期有效
alter session enable parallel dml;
對(duì)于前兩種方式,若省略num則Oracle將自動(dòng)根據(jù)負(fù)載確定并行度。并行度要隨著系統(tǒng)上工作負(fù)載的增減而變化。如果有充足的空閑資源,并行度會(huì)
上升;如果可用資源有限,并行度則會(huì)下降。這樣就不會(huì)為機(jī)器強(qiáng)加一個(gè)固定的并行度。利用這種方法,允許Oracle動(dòng)態(tài)地增加或減少查詢所需的并發(fā)資源
量。
【查看默認(rèn)并行數(shù)】
1)確定會(huì)話SID
select sid from v$mystat where rownum = 1;
2)在其他會(huì)話中查詢
select sid,qcsid,server#,degree from v$px_session where qcsid = num;
一般而言,如果能訪問盡可能多的資源(CPU、內(nèi)存和I/O),并行執(zhí)行就能最好地發(fā)揮作用。但這并不是說(shuō)如果整個(gè)數(shù)據(jù)集都在一個(gè)磁盤上,就從并行
查詢得不到任何好處。不過如果整個(gè)數(shù)據(jù)集都在一個(gè)磁盤上,可能確實(shí)不如使用多個(gè)磁盤那樣能有更多收獲。即使使用一個(gè)磁盤,在響應(yīng)時(shí)間上也可能可以得到一定
的速度提升。原因在于:給定的一個(gè)并行執(zhí)行服務(wù)器在統(tǒng)計(jì)行時(shí)并不讀取這些行,反之亦然。所以,與執(zhí)行串行相比,兩個(gè)并行執(zhí)行服務(wù)器可以在更短的時(shí)間內(nèi)完成
所有行的統(tǒng)計(jì)。
數(shù)據(jù)分布在多個(gè)物理設(shè)備上可以提高I/O,如表分區(qū)、跨磁盤等。
在Oracle 11g Release2及以上版本中,引入了一項(xiàng)新功能來(lái)限制資源過度使用:并行語(yǔ)句排除(Parallel
Statement
Queuing,PSQ)。使用PSQ時(shí),數(shù)據(jù)庫(kù)會(huì)限制并發(fā)執(zhí)行的并行查詢數(shù),并把更多的并行請(qǐng)求放在一個(gè)執(zhí)行隊(duì)列中。CPU資源用盡時(shí)數(shù)據(jù)庫(kù)會(huì)阻止新的
請(qǐng)求變?yōu)榛顒?dòng)狀態(tài)。這些請(qǐng)求并沒有失敗,它們只是會(huì)延遲開始,也就是說(shuō)它們將排隊(duì)。資源可用時(shí),數(shù)據(jù)庫(kù)就會(huì)開始執(zhí)行隊(duì)列中的查詢。
并行DML
Oracle文檔將并行DML(PDML)一詞的范圍限制為只包括INSERT、UPDATE、DELETE和MERGE(不像平常的DML那樣還
包括SELECT)。在PDML期間,Oracle可以使用多個(gè)并行執(zhí)行服務(wù)器來(lái)執(zhí)行INSERT、UPDATE、DELETE或MERGE,而不是只利
用一個(gè)串行進(jìn)程。在一個(gè)有充足I/O帶寬的多CPU主機(jī)上,對(duì)于大規(guī)模的DML操作,可能會(huì)得到很大的速度提升。
不過,不能把PDML當(dāng)成提高OLTP應(yīng)用速度的一個(gè)特性。因?yàn)椴⑿胁僮髟O(shè)計(jì)為要充分、完全地利用一臺(tái)機(jī)器上的所有資源。通過這種設(shè)計(jì),一個(gè)用戶可
以完全使用機(jī)器上的所有磁盤、CPU和內(nèi)存。在某些數(shù)據(jù)倉(cāng)庫(kù)中(有大量數(shù)據(jù),而用戶很少),這可能正是你想要的。而在一個(gè)OLTP系統(tǒng)中(大量用戶都在做
很短、很快的事務(wù)),可能就不能希望如此了,你不想讓用戶能夠完全占用機(jī)器資源。
類似于Oracle執(zhí)行的分布式查詢,PDML操作采用同樣的方式執(zhí)行,即每個(gè)并行執(zhí)行服務(wù)器相當(dāng)于一個(gè)單獨(dú)數(shù)據(jù)庫(kù)實(shí)例中的一個(gè)進(jìn)程。這些事務(wù)都結(jié)束后,會(huì)執(zhí)行一個(gè)相當(dāng)于快速2PC的過程來(lái)提交這些單獨(dú)的獨(dú)立事務(wù)。這些事務(wù)要么都由PDML協(xié)調(diào)會(huì)話提交,要么無(wú)一提交。
由于PDML采用的一種偽分布式的實(shí)現(xiàn),因此存在一些限制:
PDML操作期間不支持觸發(fā)器。這是一個(gè)很合理的限制,因?yàn)橛|發(fā)器可能會(huì)向更新增加大量開銷,而你使用PDML的本來(lái)目的是為了更快一些,這兩方面是矛盾的,不能放在一起。
PDML期間,不支持某些聲明方式的引用完整性約束,因?yàn)楸碇械拿恳黄ú糠郑?huì)在單獨(dú)的會(huì)話中作為單獨(dú)的事務(wù)進(jìn)行修改。例如,PDML操作不支持自引用完整性。如果真的支持自引用完整性,可能會(huì)出現(xiàn)死鎖和其他鎖定問題。
在提交或回滾之前,不能訪問用PDML修改的表。
PDML不支持高級(jí)復(fù)制(因?yàn)閺?fù)制特性的實(shí)現(xiàn)要基于觸發(fā)器)。
不支持延遲約束(也就是說(shuō),采用延遲模式的約束)。
如果表是分區(qū)的,PDML只可能在有位圖索引或LOB列的表上執(zhí)行,而且并行度取決于分區(qū)數(shù)。在這種情況下,無(wú)法在分區(qū)內(nèi)并行執(zhí)行一個(gè)操作,因?yàn)槊總€(gè)分區(qū)只有一個(gè)并行執(zhí)行服務(wù)器來(lái)處理。
執(zhí)行PDML時(shí)不支持分布式事務(wù)。
PDML不支持聚簇表。
并行DDL
從維護(hù)的觀點(diǎn)看,以及從管理的角度來(lái)說(shuō),并行DDL才是Oracle中并行執(zhí)行最突出的優(yōu)點(diǎn)。如果認(rèn)為并行查詢主要是為最終用戶設(shè)計(jì)的,那么并行
DDL則是為DBA/開發(fā)人員設(shè)計(jì)的。如果沒有并行執(zhí)行,DBA將很難真正充分利用硬件的全部能力。但如果利用并行執(zhí)行,則完全可以做到。以下SQL
DDL命令允許“并行化”:
CREATE INDEX:多個(gè)并行執(zhí)行服務(wù)器可以掃描表、對(duì)數(shù)據(jù)排序,并把有序的段寫出到索引結(jié)構(gòu)。
CREATE TABLE AS SELECT:執(zhí)行SELECT的查詢可以使用并行查詢來(lái)執(zhí)行,表加載本身可以并行完成。
ALTER INDEX REBUILD:索引結(jié)構(gòu)可以并行重建。
ALTER TABLE MOVE:表可以并行移動(dòng)。
ALTER TABLE SPLIT|COALESCE PARTITION:?jiǎn)蝹€(gè)表分區(qū)可以并行地分解或合并。
ALTER INDEX SPLIT PARTITION:索引分區(qū)可以并行地分解。
前4個(gè)命令還適用于單個(gè)的表/索引分區(qū),也就是說(shuō),可以并行地MOVE一個(gè)表的單個(gè)分區(qū)。
并行DDL和使用外部表的數(shù)據(jù)加載
利用并行DDL,再加上外部表,就能通過一個(gè)簡(jiǎn)單的CREATE TABLE AS SELECT or INSERT /*+ APPEND
*/來(lái)實(shí)現(xiàn)并行直接路徑加載。不用再編寫腳本,不必再分解文件,也不用協(xié)調(diào)要運(yùn)行的N個(gè)腳本。簡(jiǎn)單地說(shuō),通過結(jié)合并行DDL和外部表,不僅提供了純粹的易
用性,而且全無(wú)性能損失。
并行DDL和區(qū)段截?cái)?/p>
并行DDL依賴于直接路徑操作。也就是說(shuō),數(shù)據(jù)不傳遞到緩沖區(qū)緩存以便以后寫出;而是由一個(gè)操作(如CREATE TABLE AS
SELECT)來(lái)創(chuàng)建新的區(qū)段,并直接寫入這些區(qū)段,數(shù)據(jù)直接從查詢寫到磁盤(放在這些新分配的區(qū)段中)。每個(gè)并行執(zhí)行服務(wù)器執(zhí)行自己的部分CREATE
TABLE AS SELECT工作,并且都會(huì)寫至自己的區(qū)段。INSERT /*+ APPEND
*/(直接路徑插入)會(huì)在一個(gè)段的HWM“之上“寫,每個(gè)并行執(zhí)行服務(wù)器再寫至其自己的一組區(qū)段,而不會(huì)與其他并行執(zhí)行服務(wù)器共享。因此,如果執(zhí)行一個(gè)并
行CREATE TABLE AS
SELECT,并使用4個(gè)并行執(zhí)行服務(wù)器來(lái)創(chuàng)建表,就至少有4個(gè)分區(qū),可能還會(huì)更多。每個(gè)并行執(zhí)行服務(wù)器會(huì)分配其自己的區(qū)段,向其寫入,等填滿時(shí),再分配
另一個(gè)新的區(qū)段,并行執(zhí)行服務(wù)器不會(huì)使用由其他并行執(zhí)行服務(wù)器非品牌的區(qū)段。
在數(shù)據(jù)倉(cāng)庫(kù)環(huán)境中,執(zhí)行一個(gè)大規(guī)模的加載之后,這可能導(dǎo)致“過渡浪費(fèi)“。假設(shè)你想加載1,010MB的數(shù)據(jù)(大約1GB),而且正在使用一個(gè)有
100MB區(qū)段的表空間,你決定使用10個(gè)并行執(zhí)行服務(wù)器來(lái)加載這個(gè)數(shù)據(jù)。每個(gè)并行執(zhí)行服務(wù)器先分配其自己的100MB區(qū)段(總共會(huì)有10個(gè)100MB的
區(qū)段),并在其中填入數(shù)據(jù)。由于每個(gè)并行執(zhí)行服務(wù)器都要加載101MB的數(shù)據(jù),所以它會(huì)填滿第一個(gè)區(qū)段,然后再繼續(xù)分配另一個(gè)100MB的區(qū)段,但實(shí)際上
只會(huì)使用這個(gè)區(qū)段中1MB的空間?,F(xiàn)在就有了20區(qū)段,其中10個(gè)是滿的,另外10個(gè)則不同,這10個(gè)區(qū)段中都各有1MB的數(shù)據(jù),因此,總共會(huì)有
990MB的空間是”已分配但未使用的“。下一次加載是可以使用這個(gè)空間,但是對(duì)現(xiàn)在來(lái)說(shuō),你就有了990MB的死空間。此時(shí)區(qū)段截?cái)啵╡xtend
trimming)就能派上用場(chǎng)了。Oracle會(huì)試圖取每個(gè)并行執(zhí)行服務(wù)器的最后一個(gè)區(qū)段,并將其”截?cái)酁椤翱赡艿淖钚〈笮 ?/p>
區(qū)段截?cái)嗪妥值涔芾肀砜臻g
如果使用傳統(tǒng)的字典管理表空間,Oracle可以把只包含1MB數(shù)據(jù)的各個(gè)100MB區(qū)段轉(zhuǎn)變或1MB的區(qū)段。遺憾的是,(在字典管理的表空間中)
這會(huì)留下10個(gè)不連續(xù)的99MB空閑區(qū)段,因?yàn)槟愕姆峙錂C(jī)制采用的是100MB區(qū)段,所以這990MB空間就會(huì)用不上!下一次分配100MB時(shí),往往無(wú)法
使用現(xiàn)有的這些空間,因?yàn)楝F(xiàn)在的情況是:有99MB的空閑空間,接下來(lái)是1MB的已分配空間,然后又是99MB空閑空間,依此類推。
區(qū)段截?cái)嗪捅镜毓芾肀砜臻g
本地管理表空間有兩種類型:UNIFORM SIZE 和AUTOALLOCATE,UNIFORM
SIZE是指表空間中的每個(gè)區(qū)段大小總是完全相同;AUTOALLOCATE則表示Oracle會(huì)使用一種內(nèi)部算法來(lái)確定每個(gè)區(qū)段應(yīng)該是多大。這些方法都
能很好地解決上述問題,不過,這兩種方法的解決策略截然不同。
在字典管理的表空間中,如果請(qǐng)求一個(gè)100MB區(qū)段,倘若Oracle只找到了99MB的自由區(qū)段,請(qǐng)求還是會(huì)失敗。與字典管理表空間不同,有AUTOALLOCATE區(qū)段的本地管理表空間可以更為靈活。為了試圖使用所有空閑空間,它可以減小所請(qǐng)求的空間大小。
隨著使用并行直接路徑操作向表UNIFORM_TEST加載越來(lái)越多的數(shù)據(jù),過一段時(shí)間后,空間利用情況會(huì)變得越來(lái)越糟糕。對(duì)此,我們可能希望使用
一個(gè)更小的統(tǒng)一區(qū)段大小,或者使用AUTOALLOCATE。一段時(shí)間后,AUTOALLOCATE也可能生成更多的區(qū)段,但是由于會(huì)發(fā)生區(qū)段截?cái)?,所?/p>
空間利用情況要好得多。