使用dbms_parallel_execute來完成DML的並行
在工作中使用並行可以極大的提高工作效率。可以Object,session.hint級別引入並行。可以使大量的資料處理更加高效。
比如現在有一個表 t 有1000萬行,如果想以這個表為基礎,把資料選擇性的插入另外一個表t2,
使用Insert into t2 select *from t;
使用並行來處理也沒有問題,但是如果使用dbms_parallel_execute也是一種很不錯的選擇。
使用dbms_parallel_execute的實現方式和parallel還有一定的差別。
這個包在11g開始引入,可能初次接觸的時候會被它大量的功能所淹沒,不知道從何開始。
舉個例子來說明一下。
我們建立一個表 t,限於環境的情況,目前做一個百萬級別的資料dml操作,使用dbms_parallel_execute來完成。
建立表t.
SQL> drop table t;
Table dropped.
SQL> create table t as select object_id,object_name from dba_objects;
Table created.
建立表t2,我們專門專門多加了一個欄位。session_id。到時候會有用處。
SQL> drop table t2;
Table dropped.
SQL> create table t2 as select t1.*,0 session_id from t t1 where 1=0;
Table created.
使用如下的儲存過程來模擬一個dml的處理過程。傳入的引數,是根據rowid來處理。
create or replace procedure serial(p_lo_rid in rowid,p_hi_rid in rowid)
is
begin
for x in (select object_id object_id,object_name object_name from t where rowid between p_lo_rid and p_hi_rid)
loop
insert into t2(object_id,object_name,session_id)
values(x.object_id,x.object_name,sys_context('userenv','sessionid'));
end loop;
end;
/
使用dbms_parallel_execute來建立一個Job,以1萬條資料分單位進行資料的rowid切分。
begin
dbms_parallel_execute.create_task('PROCESS TASK');
dbms_parallel_execute.create_chunks_by_rowid
( task_name=>'PROCESS TASK',
table_owner=>user,
table_name=>'T',
by_row=>false,
chunk_size=>10000);
end;
/
透過dba_parallel_execute_chunks可以檢視到切分後的rowid情況。
set pages 200
select *from (
select chunk_id,status,start_rowid,end_rowid
from dba_parallel_execute_chunks
where task_name='PROCESS TASK'
order by chunk_id
);
檢視切分後的情況,我們可以把切分後的每一個子塊稱為chunk。可以透過這個語句來簡單的監控進度。
CHUNK_ID STATUS START_ROWID END_ROWID
---------- -------------------- ------------------ ------------------
600 UNASSIGNED AAAEQCAAFAAAACAAAA AAAEQCAAFAAAAD/CcP
601 UNASSIGNED AAAEQCAAFAAAAEAAAA AAAEQCAAFAAAAF/CcP
602 UNASSIGNED AAAEQCAAFAAAAGAAAA AAAEQCAAFAAAAH/CcP
603 UNASSIGNED AAAEQCAAFAAAAIAAAA AAAEQCAAFAAAAJ/CcP
604 UNASSIGNED AAAEQCAAFAAAAKAAAA AAAEQCAAFAAAAL/CcP
605 UNASSIGNED AAAEQCAAFAAAAWAAAA AAAEQCAAFAAAAX/CcP
606 UNASSIGNED AAAEQCAAFAAAAYAAAA AAAEQCAAFAAAAZ/CcP
607 UNASSIGNED AAAEQCAAFAAAAaAAAA AAAEQCAAFAAAAb/CcP
608 UNASSIGNED AAAEQCAAFAAAAcAAAA AAAEQCAAFAAAAd/CcP
609 UNASSIGNED AAAEQCAAFAAAEsYAAA AAAEQCAAFAAAEsfCcP
610 UNASSIGNED AAAEQCAAFAAAEsgAAA AAAEQCAAFAAAEsnCcP
可以使用如下的部分來開始處理資料。啟用了4個並行,並行度可以情況來提高。:start_id,:end_id是上面對應的rowid.
begin
dbms_parallel_execute.run_task
(task_name=>'PROCESS TASK',
sql_stmt=>'begin serial(:start_id,:end_id); end;',
language_flag=>DBMS_SQL.NATIVE,
parallel_level=>4);
end;
/
select *from (
select chunk_id,status,start_rowid,end_rowid
from dba_parallel_execute_chunks
where task_name='PROCESS TASK'
order by chunk_id
);
資料處理的進度可以檢視得到。
CHUNK_ID STATUS START_ROWID END_ROWID
---------- -------------------- ------------------ ------------------
600 PROCESSED AAAEQCAAFAAAACAAAA AAAEQCAAFAAAAD/CcP
601 PROCESSED AAAEQCAAFAAAAEAAAA AAAEQCAAFAAAAF/CcP
602 PROCESSED AAAEQCAAFAAAAGAAAA AAAEQCAAFAAAAH/CcP
603 PROCESSED AAAEQCAAFAAAAIAAAA AAAEQCAAFAAAAJ/CcP
604 PROCESSED AAAEQCAAFAAAAKAAAA AAAEQCAAFAAAAL/CcP
605 PROCESSED AAAEQCAAFAAAAWAAAA AAAEQCAAFAAAAX/CcP
606 PROCESSED AAAEQCAAFAAAAYAAAA AAAEQCAAFAAAAZ/CcP
607 PROCESSED AAAEQCAAFAAAAaAAAA AAAEQCAAFAAAAb/CcP
608 PROCESSED AAAEQCAAFAAAAcAAAA AAAEQCAAFAAAAd/CcP
處理完資料之後,就可以刪除這個job了。
begin
dbms_parallel_execute.drop_task('PROCESS TASK');
end;
/
我們可以在t2的新增列中看到每個對應的parallel處理的資料情況,可以看到資料的處理還是很平均的。
select session_id,count(*)
from t2
group by session_id
order by session_id;
SESSION_ID COUNT(*)
---------- ----------
1670371 357834
1670372 370487
1670373 403604
1670374 404679
在資料處理的時候。可以看到dbms_parallel_execute後臺啟用的處理程式和並行還是有一些不同的。
啟用了4個並行之後,看到都是j00這樣的程式。
top - 06:31:03 up 1 day, 5:21, 2 users, load average: 3.97, 1.55, 0.61
Tasks: 167 total, 4 running, 163 sleeping, 0 stopped, 0 zombie
Cpu(s): 60.7%us, 7.7%sy, 0.0%ni, 1.0%id, 28.9%wa, 0.2%hi, 1.5%si, 0.0%st
Mem: 2030124k total, 1293220k used, 736904k free, 358400k buffers
Swap: 4063224k total, 0k used, 4063224k free, 476552k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
32630 ora11g 20 0 530m 67m 64m D 55.2 3.4 0:48.34 ora_j000_TEST01
32634 ora11g 20 0 529m 60m 57m R 38.4 3.0 0:46.88 ora_j002_TEST01
32632 ora11g 20 0 529m 62m 59m R 24.8 3.2 0:44.54 ora_j001_TEST01
32636 ora11g 20 0 529m 59m 56m R 17.5 3.0 0:44.88 ora_j003_TEST01
2295 ora11g 20 0 541m 79m 67m D 1.3 4.0 0:11.93 ora_dbw0_TEST01
32706 ora11g 20 0 14940 1240 904 R 1.0 0.1 0:00.39 top -c
825 root 20 0 0 0 0 S 0.3 0.0 0:18.85 [jbd2/sdb3-8]
如果調高parallel從4到16,可以看到j00的程式相應的增加了。
top - 06:32:59 up 1 day, 5:23, 2 users, load average: 1.31, 1.29, 0.63
Tasks: 182 total, 4 running, 178 sleeping, 0 stopped, 0 zombie
Cpu(s): 77.2%us, 21.2%sy, 0.0%ni, 1.2%id, 0.2%wa, 0.0%hi, 0.2%si, 0.0%st
Mem: 2030124k total, 1345284k used, 684840k free, 358500k buffers
Swap: 4063224k total, 0k used, 4063224k free, 476800k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
404 ora11g 20 0 530m 39m 36m R 23.4 2.0 0:01.75 ora_j010_TEST01
392 ora11g 20 0 529m 33m 30m S 17.1 1.7 0:01.39 ora_j004_TEST01
402 ora11g 20 0 529m 31m 28m R 16.1 1.6 0:00.86 ora_j009_TEST01
384 ora11g 20 0 530m 35m 32m S 12.2 1.8 0:01.21 ora_j000_TEST01
386 ora11g 20 0 529m 32m 29m S 11.9 1.6 0:01.11 ora_j001_TEST01
422 root 20 0 122m 19m 10m S 11.5 1.0 0:00.35 /u04/app/11.2.0/grid/bin/crsctl.bin check has
394 ora11g 20 0 529m 31m 29m S 10.5 1.6 0:00.86 ora_j005_TEST01
410 ora11g 20 0 530m 31m 28m R 10.5 1.6 0:00.63 ora_j013_TEST01
408 ora11g 20 0 529m 32m 29m S 9.6 1.6 0:00.93 ora_j012_TEST01
388 ora11g 20 0 529m 32m 29m S 8.9 1.6 0:01.14 ora_j002_TEST01
398 ora11g 20 0 530m 32m 29m S 8.6 1.6 0:00.98 ora_j007_TEST01
390 ora11g 20 0 529m 31m 28m S 7.6 1.6 0:00.74 ora_j003_TEST01
396 ora11g 20 0 529m 32m 29m S 7.2 1.6 0:01.04 ora_j006_TEST01
406 ora11g 20 0 530m 30m 27m S 5.6 1.5 0:00.49 ora_j011_TEST01
414 ora11g 20 0 529m 29m 26m S 5.6 1.5 0:00.45 ora_j015_TEST01
400 ora11g 20 0 529m 30m 27m S 4.9 1.5 0:00.64 ora_j008_TEST01
412 ora11g 20 0 530m 30m 27m S 4.6 1.5 0:00.63 ora_j014_TEST01
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1347020/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 11G R2中的並行執行,dbms_parallel_execute並行Parallel
- 使用Flutter來完成Uplabs上炫酷的互動Flutter
- 原創:oracle DML介紹與使用Oracle
- jdbc執行DML程式設計舉例JDBC程式設計
- Docker最全教程之使用Tencent Hub來完成CI(九)Docker
- [20190120]行連結遷移與dml.txt
- 使用canvas來完成線性漸變和徑向漸變的功能Canvas
- 我用js完成了按n位數的來進行分割陣列JS陣列
- scala佇列、並行集合基本使用佇列並行
- 外來鍵沒有索引哪些DML操作會被阻塞索引
- [20230508]能否一行完成(使用tee小技巧).txt
- Oracle Parallel DMLOracleParallel
- php 非同步並行後續--相容FPM使用的元件PHP非同步並行元件
- 無索引的外來鍵之主表子表DML操作實驗及結論索引
- oracle的並行世界Oracle並行
- 人大金倉切割逗號拼接的字串,並使用in來查詢字串
- 使用.NET並行任務庫(TPL)與並行Linq(PLINQ)充分利用多核效能並行
- 使用Rust的ripunzip和rayon並行解壓縮檔案Rust並行
- 如何從GitHub上下載來客原始碼並執行?Github原始碼
- DML_The OUTPUT Clause
- Excel匯出 並完成後自動開啟Excel
- Activiti 學習(三)—— Activiti 流程啟動並完成
- Spark效能優化:提高並行度、使用reduceByKeySpark優化並行
- Pytorch使用資料並行,單機多卡PyTorch並行
- 並查集的使用並查集
- 使用Reactor完成類似的Flink的操作React
- Python的 併發、並行Python並行
- 簡寫readStream的流動模式並完成文章搜尋功能模式
- 【SpringBoot】SpringBoot + MyBatis 連線 MySQL 並完成簡單查詢的流程Spring BootMyBatisMySql
- unusable index對DML/QUERY的影響Index
- MySQL的DDL和DML操作語法MySql
- 使用並行資料倉儲所面臨的挑戰VW並行
- 一起來實現單使用者登入 —— 完成監聽
- Oracle中的並行系列(二):你設定的並行真的生效了嗎?Oracle並行
- Spring中如何使用自定義註解搭配@Import引入內外部配置並完成某一功能的啟用SpringImport
- LLM並行訓練5-MoE並行並行
- 使用dbutils完成curd操作
- Atma:完成度帶來的保真與驚喜
- 使用Github Copilot生成單元測試並執行Github