PLSQL_性能优化系列10_Oracle Array数据组优化
?2014-09-25 Created By BaoXinjian
一、摘要
集合是Oracle開發中經常遇到的情況,Oracle集合分為三種情況:索引表集合(index by table)、嵌套表集合(nested table)、可變集合(varry table)。
PL/SQL中沒有數組的概念,他的集合數據類型和數組是相似的。
- 其中varray table的元素是有數量限制的,index_by table和nexted table是沒有這個限制的。
- index-by table是稀疏的,也就是說下標可以不連續,varray table則是緊密的,他的下標沒有間隔。
- index_by table不能存儲在數據庫中,但是nexted table和varray table可以被存儲在數據庫中。
集合在使用時必須先使用type進行定義方可使用
?
二、集合的定義方式
1. 索引表集合 index by table
TYPE test_type IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;遍歷方式:這種數組不需要事先指定上限,下標可以不連續,可以是0或負數。
數據庫存放:不可以存放在數據庫中
2. 嵌套表集合 nested table
TYPE test_type IS TABLE OF VARCHAR2(10);遍歷方式:下標從1開始,不能超過數組所有元素的總和,當下標超出允許范圍時
數據庫存放:可以存放在數據庫中
3. 可變集合 varry table
TYPE test_type IS ARRARY(5) OF VARCHAR2(10);遍歷方式:由于類型定義時的元素個數限制,所以TYPE3的變量在使用時最大的元素個數不能超過5個。
數據庫存放:可以存放在數據庫中
?
三、數組的存放在數據庫方式
案例: 創建一個存在嵌套表集合類型欄位的表
Step1. 創建記錄類型Record Type
CREATE OR REPLACE TYPE bxj_record ASOBJECT (bxj_record_id NUMBER,bxj_record_date DATE,bxj_record_description VARCHAR2 (10));Step2. 創建嵌套表集合類型nested table type
CREATE OR REPLACE TYPE bxj_nested_table AS TABLE OF bxj_record;Step3. 創建測試表,用以存放集合
CREATE TABLE bxj_test_table (invoice_id NUMBER,invoice_num VARCHAR2 (10),invoice_date DATE,invoice_nested bxj_nested_table ) NESTED TABLE invoice_nested STORE AS bxj_record_tableStep4. 查看所建立的Object
Step5. 插入測試資料
DECLAREv_record1 bxj_record := bxj_record (1, SYSDATE, '2014/09/29');v_record2 bxj_record := bxj_record (2, SYSDATE, '2014/09/30');v_invoice_id NUMBER;v_invoice_num VARCHAR2 (10);v_invoice_date DATE;v_invoice_nested bxj_nested_table := bxj_nested_table (); BEGINv_invoice_id := 1;v_invoice_num := 'INVOICE_01';v_invoice_date := SYSDATE;v_invoice_nested.EXTEND;v_invoice_nested (1) := v_record1;v_invoice_nested.EXTEND;v_invoice_nested (2) := v_record2;INSERT INTO bxj_test_tableVALUES (v_invoice_id,v_invoice_num,v_invoice_date,v_invoice_nested);COMMIT; END;Step6. 查看表數據
?
四、數組優化方式 (arraysize / bulk collect)
客戶端Arraysize的設置實際上可以理解為設置數組的大小來保存sql調用的返回值。設置適當的arraysize有幾個好處:
1.減少讀data block的次數,也就是consistent gets的次數。
假設一個block有n行,如果每次取一行,則對該block的邏輯讀次數就是n,盡管邏輯讀是內存讀,速度很快,但并發量很大時也會使數據庫的壓力很大。
如果每次取>n行,則該block只需讀一次。因此合理設置arraysize能大大減輕數據庫壓力。
2.在PLSQL中減少plsql引擎和sql引擎的切換次數,提高效率
3.通過數組存放結果,減少客戶端和數據庫服務器的調用次數,減少往返時間
?
五、PLSQL Bulk Collect設置數組訪問的方法
案例:測試Bulk Collect訪問數組的限制對consistent gets和script run time的影響
測試一:不使用bulk collect,一次fetch一條記錄
Step2. 運行測試腳本
DECLARECURSOR c1ISSELECT object_nameFROM all_objectsWHERE ROWNUM < 100000;v_id VARCHAR2 (30); BEGINOPEN c1;LOOPFETCH c1 INTO v_id;EXIT WHEN c1%NOTFOUND;NULL;END LOOP;CLOSE c1; END; /Step3. 查看運行后consisten gets變化 = 235622 -109441 = 126811
?
測試二:設置bulk collect,一次取100條
Step1. 運行測試腳本
DECLARETYPE VarcharTabISTABLE OF VARCHAR2 (30)INDEX BY BINARY_INTEGER;CURSOR c1ISSELECT object_nameFROM all_objectsWHERE ROWNUM < 100000;v_id VarcharTab; BEGINOPEN c1;LOOPFETCH c1 BULK COLLECT INTO v_id LIMIT 100;EXIT WHEN c1%NOTFOUND;NULL;END LOOP;CLOSE c1; END; /Step2. 查看運行后consisten gets變化 = 284623 -235622= 49001
?
測試三:設置bulk collect,一次取5000條
Step1. 運行測試腳本
DECLARETYPE VarcharTabISTABLE OF VARCHAR2 (30)INDEX BY BINARY_INTEGER;CURSOR c1ISSELECT object_nameFROM all_objectsWHERE ROWNUM < 100000;v_id VarcharTab; BEGINOPEN c1;LOOPFETCH c1 BULK COLLECT INTO v_id LIMIT 5000;EXIT WHEN c1%NOTFOUND;NULL;END LOOP;CLOSE c1; END; /Step2. 查看運行后consisten gets變化 = 332559 -284623= 47936
?
測試結果
- 測試一:consisten gets變化 = 235622 -109441= 126811
- 測試二:consisten gets變化 = 284623 -235622= 49001
- 測試三:consisten gets變化 = 332559 -284623= 47936
consistent_gets是從回滾段中讀到的前映(或叫讀取一致性影象), 看見的數據是查詢開始的時間點的,所以若存在block在查詢開始后發生了變化的情況,則必須產生 before image 然后讀數據,這就是一致讀的含義
查詢就是表示 consistent gets (query mode),因為查詢要保證所獲取的數據的時間點的一致性,所以叫一致讀,
即使是從當前 buffer 獲得的數據,也叫 consistent gets ,這僅僅表達一種模式一種期望,并不表示真實的是從 當前buffer 獲得 還是從回滾段獲取數據產生的 bufore image 。
?
網絡上的一個測試結果
?
六、SQLPLUS設置數組訪問的方法
Sqlplus的arraysize參數表示數據庫一次返回給客戶端的行數,缺省是15。
如果返回數據量大,可以調大此參數:Set arraysize nnnn, 該參數最大為5000。
?
測試一:缺省arraysize ?
select * from all_objects where rownum <100000;查看執行時間
?
測試二:SQL> set arraysize 1000 ?
select * from all_objects where rownum <100000;查看執行時間
?
Thanks and Regards
參考:http://www.jb51.net/article/35424.htm
轉載于:https://www.cnblogs.com/eastsea/p/3981038.html
總結
以上是生活随笔為你收集整理的PLSQL_性能优化系列10_Oracle Array数据组优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 5.0 API 的变化—
- 下一篇: MySQL数据库安装与配置详解