oracle 批量读,Oracle批量读取数据和批量绑定
通常我們獲取游標數據是用
fetch some_cursor into var1, var2 的形式,自 Oracle 8i 起,Oracle 為我們提供了
fetch bulk
collect?來批量取游標中的數據,它能在讀取游標中大量數據的時候提升效率,采用bulk
collect可以將查詢結果一次性地加載到collections中。而不是通過cursor一條一條地處理。
Bulk
Collect批查詢在某種程度上可以提高查詢效率,它首先將所需數據讀入內存,然后再統計分析,這樣就可以提高查詢效率。但是,如果Oracle數據庫的內存較小,Shared
Pool Size不足以保存Bulk Collect批查詢結果,那么該方法需要將Bulk
Collect的集合結果保存在磁盤上,在這種情況下,Bulk Collect方法的效率會較低;
fetch bulk
collect into 的使用格式是:fetch some_cursor bulk collect into col1, col2
limit xxx。col1、col2 是聲明的集合類型變量,xxx 為每次取數據塊的大小(記錄數),相當于緩沖區的大小,可以不指定
limit xxx 大小。
測試實例:
--
1000000行數據使用批量fetch方式,執行時間1s
declare
type id_type is table of
emp.EMPNO%type;
v_id
id_type;
type name_type is table of
emp.ENAME%type;
v_name
name_type;
type sal_type is table of
emp.SAL%type;
v_sal
sal_type;
cursor all_emp
is
select empno,ename,sal from emp2
where rownum <= 1000000;
begin
open
all_emp;
loop
fetch all_emp bulk collect into
v_id,v_name,v_sal limit
256;
for i in 1..v_id.count
loop
null;
end
loop;
exit when
all_emp%notfound;
end
loop;
close all_emp;
end;
--1000000行數據使用逐行fetch方式執行時間11s
declare
v_id
emp2.EMPNO%type;
v_name
emp2.ename%type;
v_sal
emp2.sal%type;
cursor all_emp
is
select empno,ename,sal from emp2
where rownum <=
1000000;
begin
open
all_emp;
loop
fetch all_emp into
v_id,v_name,v_sal;
exit when
all_emp%notfound;
null;
end
loop;
close all_emp;
end;
幾點說明:
1、?從測試結果來看游標的記錄數越大時,用 fetch bulk
collect into 的效率很明顯示,趨于很小時就差不多了。
2、?可以在select into,fetch
into,returning into語句使用bulk collect。
3、?在使用bulk
collect時,所有的into變量都必須是collections
4、?在這個例子中,我們借助于集合的 first、last
、count?來進行遍歷。
5、?關于 limit 參數
6、?你可以根據你的實際來調整 limit
參數的大小,來達到你最優的性能。limit 參數會影響到 pga 的使用率。而且也可以在 fetch bulk 中省略 limit
參數,寫成
fetch all_contacts_cur bulk collect into
v_contacts;
不寫 limit 參數時,可以去除外層循環,begin-end 部分可寫成:
begin
open
all_emp;
fetch all_emp bulk collect into
v_id,v_name,v_sal;
for i in 1..v_id.count
loop
null;
end
loop;
close all_emp;
end;
除了Bulk
Collect批查詢外,我們還可以使用FORALL語句來實現批插入、刪除和更新,這在大批量數據操作時可以顯著提高執行效率
使用FORALL比FOR效率高,因為前者只切換一次上下文,而后者將是在循環次數一樣多個上下文間切換。
--FOR用法 ,9s
DECLARE
TYPE ID_TYPE IS TABLE OF
EMP.EMPNO%TYPE;
V_ID
ID_TYPE;
TYPE NAME_TYPE IS TABLE OF
EMP.ENAME%TYPE;
V_NAME
NAME_TYPE;
TYPE SAL_TYPE IS TABLE OF
EMP.SAL%TYPE;
V_SAL
SAL_TYPE;
CURSOR ALL_EMP
IS
SELECT EMPNO,ENAME,SAL FROM EMP2
WHERE ROWNUM <= 200000;
BEGIN
OPEN
ALL_EMP;
FETCH ALL_EMP BULK COLLECT INTO
V_ID,V_NAME,V_SAL;
FOR I IN 1..V_ID.COUNT
LOOP
insert into t(id)
values(V_ID(i));
END
LOOP;
CLOSE ALL_EMP;
END;
--FORALL用法 ,5S
DECLARE
TYPE ID_TYPE IS TABLE OF
EMP.EMPNO%TYPE;
V_ID
ID_TYPE;
TYPE NAME_TYPE IS TABLE OF
EMP.ENAME%TYPE;
V_NAME
NAME_TYPE;
TYPE SAL_TYPE IS TABLE OF
EMP.SAL%TYPE;
V_SAL
SAL_TYPE;
CURSOR ALL_EMP
IS
SELECT EMPNO,ENAME,SAL FROM EMP2
WHERE ROWNUM <= 200000;
BEGIN
OPEN
ALL_EMP;
FETCH ALL_EMP BULK COLLECT INTO
V_ID,V_NAME,V_SAL
;
FORALL I IN
1..V_ID.COUNT
insert into t(id)
values(V_ID(i));
CLOSE ALL_EMP;
END;
總結
以上是生活随笔為你收集整理的oracle 批量读,Oracle批量读取数据和批量绑定的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 打印值,oracle –
- 下一篇: eslint php,ESlint操作步