批量更新資料方法比較測試
很多情況下,我們會遇到大資料量的批量更新要求,下面,我就來按照rowid的方式(這應該是最快的方法),來比較幾種處理方式之間的效能差異,由於機器效能(PC機)及時間原因,這裡只准備了460W條資料,比較各種方案迴圈處理的時間,比較結果。
SQL> select count(1) from testA;
COUNT(1)
----------
4643600
SQL> set timing on
第一種情況,無序rowid的遊標迴圈更新:
SQL> declare
cursor upd_cursor is
select rowid as row_id from testA;
rowd varchar(30);
v_counter number;
begin
open upd_cursor;
loop
fetch upd_cursor
into rowd;
exit when upd_cursor%notfound;
execute immediate 'update testA set flag=:f where rowid=:r'
using 1, rowd;
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
close upd_cursor;
commit;
end;
/
cursor upd_cursor is
select rowid as row_id from testA;
rowd varchar(30);
v_counter number;
begin
open upd_cursor;
loop
fetch upd_cursor
into rowd;
exit when upd_cursor%notfound;
execute immediate 'update testA set flag=:f where rowid=:r'
using 1, rowd;
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
close upd_cursor;
commit;
end;
/
PL/SQL 過程已成功完成。
已用時間: 00: 05: 46.78
第二種情況,有序rowid的遊標迴圈更新:
SQL> declare
cursor upd_cursor is
select rowid as row_id from testA order by rowid;
rowd varchar(30);
v_counter number;
begin
open upd_cursor;
loop
fetch upd_cursor
into rowd;
exit when upd_cursor%notfound;
execute immediate 'update testA set flag=:f where rowid=:r'
using 1, rowd;
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
close upd_cursor;
commit;
end;
/
cursor upd_cursor is
select rowid as row_id from testA order by rowid;
rowd varchar(30);
v_counter number;
begin
open upd_cursor;
loop
fetch upd_cursor
into rowd;
exit when upd_cursor%notfound;
execute immediate 'update testA set flag=:f where rowid=:r'
using 1, rowd;
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
close upd_cursor;
commit;
end;
/
PL/SQL 過程已成功完成。
已用時間: 00: 05: 30.03
第三種情況,無序rowid的bulk collect更新:
SQL> declare
type objecttab is table of varchar2(20);
rowd objecttab;
cursor upd_cursor is
select rowid as row_id from testA;
v_counter number;
begin
open upd_cursor;
fetch upd_cursor bulk collect
into rowd;
close upd_cursor;
for i in rowd.first .. rowd.last loop
execute immediate 'update testA set flag=:f where rowid=:r'
using 2, rowd(i);
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
commit;
end;
/
type objecttab is table of varchar2(20);
rowd objecttab;
cursor upd_cursor is
select rowid as row_id from testA;
v_counter number;
begin
open upd_cursor;
fetch upd_cursor bulk collect
into rowd;
close upd_cursor;
for i in rowd.first .. rowd.last loop
execute immediate 'update testA set flag=:f where rowid=:r'
using 2, rowd(i);
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
commit;
end;
/
PL/SQL 過程已成功完成。
已用時間: 00: 04: 29.80
第四種情況,有序rowid的bulk collect更新:
SQL> declare
type objecttab is table of varchar2(20);
rowd objecttab;
cursor upd_cursor is
select rowid as row_id from testA order by rowid;
v_counter number;
begin
open upd_cursor;
fetch upd_cursor bulk collect
into rowd;
close upd_cursor;
for i in rowd.first .. rowd.last loop
execute immediate 'update testA set flag=:f where rowid=:r'
using 2, rowd(i);
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
commit;
end;
/
type objecttab is table of varchar2(20);
rowd objecttab;
cursor upd_cursor is
select rowid as row_id from testA order by rowid;
v_counter number;
begin
open upd_cursor;
fetch upd_cursor bulk collect
into rowd;
close upd_cursor;
for i in rowd.first .. rowd.last loop
execute immediate 'update testA set flag=:f where rowid=:r'
using 2, rowd(i);
if (v_counter >= 1000) then
commit;
v_counter := 0;
end if;
end loop;
commit;
end;
/
PL/SQL 過程已成功完成。
已用時間: 00: 04: 41.76
最後,再來看看forall,對於這種迴圈,建議更新的資料量不要太大,效果還是可以的,對於這裡的資料量已經不合適。
SQL> declare
type objecttab is table of varchar2(20);
rowd objecttab;
cursor upd_cursor is
select rowid as row_id from testA order by rowid;
v_counter number;
begin
open upd_cursor;
fetch upd_cursor bulk collect
into rowd;
close upd_cursor;
forall i in rowd.first .. rowd.last execute immediate
'update testA set flag=:f where rowid=:r' using 1,
rowd(i)
;
commit;
end;
/
type objecttab is table of varchar2(20);
rowd objecttab;
cursor upd_cursor is
select rowid as row_id from testA order by rowid;
v_counter number;
begin
open upd_cursor;
fetch upd_cursor bulk collect
into rowd;
close upd_cursor;
forall i in rowd.first .. rowd.last execute immediate
'update testA set flag=:f where rowid=:r' using 1,
rowd(i)
;
commit;
end;
/
手動給停止了,這種資料級一次性提交太不合適了。
總結:對於這個資料量級的更新,是否按rowid的順序去更新,對效能的影響不是很大,可能和我資料的儲存有關(測試資料是我一次性插入的,可能分佈本身就很連續了)。若是那種分佈不連續,而且資料量很大的話,按rowid順序會去讀取更新快些。還有,貌似bulk collect適當使用,效率會比遊標的效率更高。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9399028/viewspace-684553/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 批量更新效能比較
- DataTable資料批量寫入資料庫三種方法比較資料庫
- zt_Oracle批量更新】根據一個大表批量更新另一大表的方法比較Oracle
- ORACLE批次更新四種方法比較Oracle
- 軟體測試工具比較
- [shell基礎]——整數比較;字串比較;檔案測試;邏輯測試符字串
- 如何批量更新資料
- pymysql批量更新資料MySql
- 資料庫-批量更新資料庫
- Apache Pulsar 與 Kafka 效能比較:延遲性(測試方法)ApacheKafka
- 自動化測試框架比較框架
- sqlldr批量匯入匯出資料測試SQL
- oracle批量新增更新資料Oracle
- 關閉資料庫比較好的方法資料庫
- python 批量resize效能比較Python
- 滲透測試與自動化安全測試工具比較
- 海量資料處理_批量更新
- PyPy 和 CPython 的效能比較測試Python
- Ibatis批量更新資料(mysql資料庫)BATMySql資料庫
- 圖資料庫比較資料庫
- 資料結構比較資料結構
- 主流資料庫比較資料庫
- Apache Prefork和Worker模式的效能比較測試Apache模式
- SQL隱碼攻擊漏洞測試工具比較SQL
- 【MyBatis】幾種批量插入效率的比較MyBatis
- HHDESK資料夾比較功能
- MySQL大量資料插入各種方法效能分析與比較MySql
- 關於驗證表中有無資料的方法比較
- oracle資料庫兩表資料比較Oracle資料庫
- 集合差異比較演算法及效能測試演算法
- MySQL中的批量初始化資料的對比測試(r12筆記第71天)MySql筆記
- 水煮oracle29----oracle中對資料的批量操作測試Oracle
- IMUSTOJ運維——批量自動化生成題目測試資料運維
- 資料庫執行效率的對比測試資料庫
- Oracle批次插入測試資料的方法Oracle
- 迅速插入大量測試資料的方法
- 批量插入 1 萬條資料,DB 查詢構造器和原生 SQL 效能比較SQL
- 77種資料建模工具比較