PL/SQL中的forall简单测试
之前写过一篇bulk collect的文章,只是对于bulk collect做了简单的实例。http://www.linuxidc.com/Linux/2015-07/119948.htm其实
之前写过一篇bulk collect的文章,只是对于bulk collect做了简单的实例。
其实不光是bulk collect,forall对于pl/sql的性能的提升也是相当大的。
可以参见下面的两个图,可以看到其实在pl/sql中,可能很多时候我们所写的pl/sql代码会在sql引擎和plsql引擎建进行上下文的切换,这个过程还是很耗费时间的。
而forall却是相反,是提供一次上下文切换,会在forall的过程中进行数据的包装处理。一次发送给sql执行器去处理,大大减少了上下文切换时间。
对于此,可以想象,如果cursor中的结果集很庞大,就很可能进行大量的上下文切换,导致执行速度骤降。
我们来做一个简单的实例来说明一下。
我们创建一个表test_data,里面大概有7万多的数据量。
n1@TEST11G> create table test_data as select *from all_objects;
Table created.
n1@TEST11G> select count(*)from test_data;
COUNT(*)
----------
71659
1 row selected
n1@TEST11G> create unique index inx_test_data_pk on test_data(object_id);
Index created.
Elapsed: 00:00:00.48
然后就开始执行存储过程
[ora11g@oel1 plsql]$ cat a.sql
create or replace procedure test_proc as
cursor test_cur is select *from test_data;
i number;
begin
i:=1;
for cur in test_cur
loop
update test_data set object_name=cur.object_name
where object_id=cur.object_id;
dbms_output.put_line('this is a test');
i:=i+1;
end loop;
end;
/
exec test_proc;
执行的过程中会看到进程占用了大量的cpu资源。可见进行了大量的上下文切换。其实一个主要的信息点就是可以看到输出了大量的日志内容,,最后还因为缓存的原因退出了。
......
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
this is a test
BEGIN test_proc; END;
*
ERROR at line 1:
ORA-20000: ORU-10027: buffer overflow, limit of 1000000 bytes
ORA-06512: at "SYS.DBMS_OUTPUT", line 32
ORA-06512: at "SYS.DBMS_OUTPUT", line 97
ORA-06512: at "SYS.DBMS_OUTPUT", line 112
ORA-06512: at "N1.TEST_PROC", line 10
ORA-06512: at line 1
Elapsed: 00:00:13.73
同样的要求,如果使用forall的形式,使用的代码如下。
[ora11g@oel1 plsql]$ cat b.sql
create or replace procedure test_proc as
cursor test_cur is select *from test_data;
type rec_type is table of test_cur%rowtype index by binary_integer;
recs rec_type;
begin
open test_cur;
fetch test_cur bulk collect into recs;
close test_cur;
forall i in 1..recs.COUNT
update test_data set object_name=recs(i).object_name
where object_id=recs(i).object_id;
dbms_output.put_line('this is a test');
end;
/
这种效果就好得多,可以看到日志中只输出了一次日志信息,意味着只进行了一次上下文切换,这种方法明显要好很多。
n1@TEST11G> exec test_proc;
this is a test
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.67
对于大批量的数据处理还是很值得推荐的。后续会使用dbms_profiler来对此测试一下,可以看出在一些实现点中还是存在着很大的不同。
Oracle数据库之PL/SQL程序基础设计
PL/SQL Developer实用技巧分享
本文永久更新链接地址:

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

蘋果公司最新發布的iOS18、iPadOS18以及macOSSequoia系統為Photos應用程式增添了一項重要功能,旨在幫助用戶輕鬆恢復因各種原因遺失或損壞的照片和影片。這項新功能在Photos應用的"工具"部分引入了一個名為"已恢復"的相冊,當用戶設備中存在未納入其照片庫的圖片或影片時,該相冊將自動顯示。 "已恢復"相簿的出現為因資料庫損壞、相機應用未正確保存至照片庫或第三方應用管理照片庫時照片和視頻丟失提供了解決方案。使用者只需簡單幾步

Hibernate多態映射可映射繼承類別到資料庫,提供以下映射類型:joined-subclass:為子類別建立單獨表,包含父類別所有欄位。 table-per-class:為子類別建立單獨資料表,僅包含子類別特有列。 union-subclass:類似joined-subclass,但父類別表聯合所有子類別列。

PHP處理資料庫連線報錯,可以使用下列步驟:使用mysqli_connect_errno()取得錯誤代碼。使用mysqli_connect_error()取得錯誤訊息。透過擷取並記錄這些錯誤訊息,可以輕鬆識別並解決資料庫連接問題,確保應用程式的順暢運作。

如何在PHP中使用MySQLi建立資料庫連線:包含MySQLi擴充(require_once)建立連線函數(functionconnect_to_db)呼叫連線函數($conn=connect_to_db())執行查詢($result=$conn->query())關閉連線( $conn->close())

在Golang中使用資料庫回呼函數可以實現:在指定資料庫操作完成後執行自訂程式碼。透過單獨的函數新增自訂行為,無需編寫額外程式碼。回調函數可用於插入、更新、刪除和查詢操作。必須使用sql.Exec、sql.QueryRow或sql.Query函數才能使用回呼函數。

可以透過使用gjson函式庫或json.Unmarshal函數將JSON資料儲存到MySQL資料庫中。 gjson函式庫提供了方便的方法來解析JSON字段,而json.Unmarshal函數需要一個目標類型指標來解組JSON資料。這兩種方法都需要準備SQL語句和執行插入操作來將資料持久化到資料庫中。

透過Go標準庫database/sql包,可以連接到MySQL、PostgreSQL或SQLite等遠端資料庫:建立包含資料庫連接資訊的連接字串。使用sql.Open()函數開啟資料庫連線。執行SQL查詢和插入操作等資料庫操作。使用defer關閉資料庫連線以釋放資源。

在C++中使用DataAccessObjects(DAO)函式庫連接和操作資料庫,包括建立資料庫連線、執行SQL查詢、插入新記錄和更新現有記錄。具體步驟為:1.包含必要的函式庫語句;2.開啟資料庫檔案;3.建立Recordset物件執行SQL查詢或操作資料;4.遍歷結果或依照特定需求更新記錄。
