Sql優化 三 關於oracle的併發

2021-09-08 19:20:32 字數 3620 閱讀 7875

oracle的併發技術可以將乙個大任務分解為多個小任務由多個程序共同完成。合理地使用併發可以充分利用系統資源,提高效率。

一、 併發的種類

parallel query

parallel dml(pdml)

parallel ddl

parallel recovery

[@more@]

二、 適用場合

適用parallel的兩個條件

1)大的任務,如全表掃瞄大表

這和日常生活中的經驗是一樣的,小任務自己完成都比派發任務省事

2)系統有足夠的資源(cpu/io)

換句話說,併發是在系統資源充足、使用者少的系統上,為了充分利用系統資源以提高任務處理速度而設計的一種技術。以下是幾種場景:

1)oltp系統 有大量使用者和session,如果每個session使用併發查詢將導致系統崩潰。但也有例外例如計費系統月底或下班後沒有或使用者很少訪問,執行批處理程式,此時可使用併發提高速度

2)資料倉儲系統 通常可使用併發查詢、pdml等併發,注意有些資料倉儲系統也提供給大量使用者訪問,這種系統有某些oltp特性,應慎用併發

3)無論是oltp還是資料倉儲,維護期間使用parallel ddl和pdml對管理員來說是非常有用的

三、 parallel query

使用併發查詢的方法:

1)修改表屬性

alter table big_table parallel 4;

alter table big_table parallel ;由oracle根據系統資源情況決定。這是推薦的.oracle根據cpu數目乘以parallel threads per cpu引數(default 2),例如4cpu的機器,oracle決定parallel數目為8

2)使用hint , select * /*+ parallel(emp,12) */ …

表空間的extent管理有兩種方式,unform size,則每個extent大小相同,autoallocate是oracle根據內部機制決定extent大小,更靈活

uniform 方式不支援extent trimming,而autoallocate在parallel ddl中用到extent trimming,減少了空間浪費。

因此在頻繁使用parallel ddl操作的表空間上,要麼減少uniform size每個extent的大小,要麼使用autoallocate ,以減少空間浪費。

六、 併發diy-儲存過程的併發

以下是乙個常見任務:掃瞄全表,修改資料,再寫入新的表

如果乙個程序處理太慢,我們通常會自己將資料劃分,然後開多個程序呼叫。

使用11gr2 內建的並發包:dbms_paralllel_execute,大大簡化了這一過程

(11gr2之前,沒有內建的併發程式包,需要手工按照rowid或主鍵劃分大表,然後通過dbms_job或dbms_schedule併發呼叫。)

我們以前兩天***的乙個程式為例,看看如何使用這一併發技術(本例較簡單,不見得需要使用這樣技術,僅僅作為例子來說明)

程式的目的是刪除bmf中orig_bill_ref_no like '18%'的記錄,本來一句sql可以完成,由於資料量太大,系統回滾段不足。因此開發人員準備分多個程序執行

declare

cursor c1

is select orig_bill_ref_no from bmf where orig_bill_ref_no like '18%'

and mod(account_no, 5) = 0; (將資料分為5段)

begin

for r1 in c1 loop

delete from bmf where orig_bill_ref_no = r1.orig_bill_ref_no;

commit;

end loop;

commit;

end;

/這 樣的寫法會有什麼問題呢,很快就遇到snapshot too old錯誤了。原因是select開啟bmf游標,同時修改bmf並commit資料,由於查詢一致性要求,開啟的游標要看到的是bmf修改之前的情況, 這是從undo去讀的,因此一旦時間超出undo_retention,undo資訊過期,就報snapshot too old了。

使用ora11g提供的並發包的寫法:

1) 建立過程serial過程,用來被多個併發執行緒呼叫

create or replace

procedure serial( p_lo_rid in rowid, p_hi_rid in rowid )

isbegin

delete from bmf

where rowid between p_lo_rid and p_hi_rid and orig_bill_ref_no like '15%';

end;

/2) 按照rowid將表劃分為多個chunk,供執行緒呼叫

begin

dbms_parallel_execute.create_task('process big table');

dbms_parallel_execute.create_chunks_by_rowid

( task_name => 'process big table',

table_owner => 'luw',

table_name => 'bmf',

by_row => false, --不按行記錄數而按block數

chunk_size => 2000 );

end;

/select *

from (

select chunk_id, status, start_rowid, end_rowid

from dba_parallel_execute_chunks

where task_name = 'process big table'

order by chunk_id

)where rownum <= 5

/3) 發起併發任務,按照第2步對表的劃分來分配並執行任務

begin

dbms_parallel_execute.run_task

( task_name => 'process big table',

sql_stmt => 'begin serial( :start_id, :end_id ); end;',

language_flag => dbms_sql.native,

parallel_level => 4 );

end;

/4) 刪除併發作業

begin

dbms_parallel_execute.drop_task('process big table' );

end;

/ 那麼使用併發和簡單的delete相比,速度怎樣呢

使用併發:

pl/sql procedure successfully completed.

elapsed: 00:00:03.07

直接delete:

delete from bmf where orig_bill_ref_no like '15%';

403525 rows deleted.

elapsed: 00:00:08.12

這說明使用併發提高了速度,更別說對回滾段的空間要求也少了。

EOS系列三 關於ABI檔案

1 簡介 eos開發工具包eosio.cdt中的eosio cpp可以根據合約 自動生成abi檔案,但在某些情況下 一些c 高階特性的使用以及某些自定義型別的使用 自動生成失敗,則需要了解abi檔案的工作機制,以便debug你的 其實abi檔案就是用json格式進行合約的結構描述,包括合約 中定義的...

劍指offer三 關於sizeof

通常語言面試有3種型別,第一種型別是面試官直接詢問應聘者對c 概念我的理解。這種型別的問題,面試官特別喜歡了解應聘者對c 關鍵字的理解程度。例如 在c 中,有哪4個與型別轉換相關的關鍵字?這些關鍵字各有什麼特點,應該在什麼場合下使用?在這種型別的題目中,sizeof是經常被問道的乙個概念。比如下面的...

關於「井字過三關」遊戲

有段c程式,編譯不出來,無法交作業 include typedef char chess 10 typedef int temparr 10 chess arr temparr brr int number,sye,c3,n2,c2,n1,c1 char ch void inarrdata ches...