pl/sql儲存過程優化一例
問題提出:
etl中有一過程qmsressummt0_test,用來抽取各地xxx應用的資料,目前處於測試階段,暫時存放2個廠區一個月的測試資料,目前該過程執行一次要30分鐘,按此狀況,日後如再抽取其他廠區的資料,預計執行三個小時以上,小組開發人員請求協助優化。
優化前的執行情況
9:31:20 SQL> set serveroutput on;
9:31:25 SQL> exec qmsressummt0_test;
PL/SQL procedure successfully completed
10:00:54 SQL>
執行一次,耗時在30分鐘
調優步驟:
步驟一:調整sql的優化器由rbo變為採用cbo方式
檢視procedure涉及到table的統計資訊,三個表都沒有統計資訊
10:33:35 SQL> select * from user_tables where table_name in ('QMS310T0','QMS311T0',UPPER('qmsressummt0'));
TABLE_NAME TABLESPACE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE
------------------------------ --------------------------- ---------- ------------ ----------
QMS310T0 QMSS
QMS311T0 QMSS
QMSRESSUMMT0 QMSS
Oracle9i,10g的sql優化器優先採用cbo方式,cbo方式下,oracle優化器可以更智慧更合理的選擇執行計劃,從而使sql的執行效率更高,而若相關table和index沒有統計資訊的話,則會轉而採用傳統的rbo方式,在此例子中,任意檢視過程中的某個sql,發現都是採用rbo。
接下來分析該過程涉及到的三個表,收集相關統計資訊。
對這三個表做分析,收集統計資訊
10:00:54 SQL> analyze table qms310t0 compute statistics for table for all indexes;
Table analyzed
10:33:11 SQL> analyze table qms311t0 compute statistics for table for all indexes;
Table analyzed
10:33:21 SQL> analyze table qmsressummt0 compute statistics for table for all indexes;
Table analyzed
10:33:35 SQL>
可以試驗比對一下,採用rbo和cbo的執行效率對比情況
10:41:43 SQL> exec qmsressummt0_test;
PL/SQL procedure successfully completed
11:03:37 SQL>
可以發現,現在的執行時間在20分鐘,在此過程中,效率提高了接近1/3,由此,我們可以看到相同的sql語句,優化器採用cbo比採用rbo效率要提高不少。
步驟二:合理利用索引,進一步提高sql執行效率
分析procedure和table,相關的表需要建立索引,這一步需要根據以往的經驗,建立相關索引(開發人員並沒有考慮新增索引,甚至主鍵都沒有),並抽取sql語句,檢視索引新增前後的執行計劃,最終建立的索引(主鍵索引)如下
SQL> alter table QMS310t0
add constraint PK1_QMS310T0 primary key (BRANCH_NO, CHECK_NO,vend_id,mtrl_no)
Using Index tablespace indx;
Table altered
SQL> alter table QMS311t0
add constraint PK1_QMS311T0 primary key (BRANCH_NO, CHECK_NO, SAMPL_NO,mtrl_no, CHK_NO)
Using Index tablespace indx ;
Table altered
SQL>alter table qmsressummt0 add constraint pk_qmsresssummt0 primary key (yyyymm,branch_no,vend_id,mtrl_no,chk_no) using index tablespace indx;
Table altered
SQL> create index idx_qms310t0_ymd on qms310t0(yymmdd) tablespace indx;
Index created
再次執行過程
11:43:51 SQL> exec qmsressummt0_test;
PL/SQL procedure successfully completed
11:49:34 SQL>
時間大約為6分鐘。
步驟三:合理的改變業務處理方式,亦可提高程式執行效率
對該過程的深入分析可以發現,其中的max 最大值,min 最小值,和count(*) 三個sql語句可以合併成一個sql語句,這樣同樣可以達到減少sql的執行次數和資料塊的io數量,提高效率和降低執行時間的目的。
修改前的sql語句 | 修改後的sql語句
select max(b.item_val) | select max(b.item_val),min(b.item_val),Count(*)
into v_chk_max | into v_chk_max,v_chk_min,v_cnt_01
from qms310t0 a, qms311t0 b | from qms310t0 a, qms311t0 b
where a.check_no = b.check_no | where a.check_no = b.check_no
and a.branch_no = b.branch_no | and a.branch_no = b.branch_no
and a.mtrl_no = r1.mtrl_no | and a.mtrl_no = r1.mtrl_no
and a.vend_id = r1.vend_id | and a.vend_id = r1.vend_id
and a.branch_no = r1.branch_no | and a.branch_no = r1.branch_no
and b.chk_no = r1.chk_no; | and b.chk_no = r1.chk_no;
|
select min(b.item_val) |
into v_chk_min |
from qms310t0 a, qms311t0 b |
where a.check_no = b.check_no |
and a.branch_no = b.branch_no |
and a.mtrl_no = r1.mtrl_no |
and a.vend_id = r1.vend_id |
and a.branch_no = r1.branch_no |
and b.chk_no = r1.chk_no; |
SELECT count(*) |
INTO v_cnt_01 |
FROM qms311t0 a, qms310t0 b |
WHERE a.branch_no = r1.branch_no |
AND a.mtrl_no = r1.mtrl_no |
AND a.chk_no = r1.chk_no |
and a.check_no = b.check_no |
and a.branch_no = b.branch_no; |
執行的情況:
15:31:13 SQL> exec qmsressummt0_test
PL/SQL procedure successfully completed
15:33:42 SQL>
最終,該過程執行的時間<3分鐘 。
至此,程式執行效率提高10倍左右,調整優化結束。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10159839/viewspace-154887/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle Pl/SQL 之 儲存過程OracleSQL儲存過程
- PL/SQL 05 儲存過程 procedureSQL儲存過程
- PL/SQL優化一例SQL優化
- PL/SQL中動態掉用儲存過程SQL儲存過程
- PL/SQL 中的儲存過程與函式SQL儲存過程函式
- 編寫和優化SQL Server的儲存過程優化SQLServer儲存過程
- 使用儲存過程(PL/SQL)向資料庫中儲存BLOB物件儲存過程SQL資料庫物件
- mysql儲存過程一例MySql儲存過程
- pl/sql developer除錯儲存過程報錯處理SQLDeveloper除錯儲存過程
- SQL Server儲存過程的優缺點SQLServer儲存過程
- 儲存過程優化(DBMS_HPROF)儲存過程優化
- SQL儲存過程示例SQL儲存過程
- SQL Server 儲存過程SQLServer儲存過程
- 【SQL Server】--儲存過程SQLServer儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- Oracle儲存過程優化小實踐Oracle儲存過程優化
- oracle pl/sql儲存過程內外層遊標cursor巢狀引數化示例OracleSQL儲存過程巢狀
- 儲存過程中DDL錯誤一例儲存過程
- SQL 分頁儲存過程SQL儲存過程
- MS SQL Server儲存過程SQLServer儲存過程
- Sql Server系列:儲存過程SQLServer儲存過程
- SQL 建立儲存過程PROCEDURESQL儲存過程
- 解密SQL SERVER儲存過程解密SQLServer儲存過程
- SQL儲存過程迴圈SQL儲存過程
- sql儲存過程分頁SQL儲存過程
- oracle中取得儲存過程、函式等pl sql原始碼的方法Oracle儲存過程函式SQL原始碼
- oracle procedure儲存過程(pl/sql)_使用declare cursor_begin end巢狀Oracle儲存過程SQL巢狀
- Oracle優化案例-儲存過程的優化思路(二十三)Oracle優化儲存過程
- 兩種SQL分頁方法儲存過程和遊標儲存過程SQL儲存過程
- Sql儲存過程分頁--臨時表儲存SQL儲存過程
- sql 儲存過程命名規範SQL儲存過程
- SQL Server基礎:儲存過程SQLServer儲存過程
- sql server儲存過程語法SQLServer儲存過程
- SQL總結(五)儲存過程SQL儲存過程
- SQL server儲存過程函式SQLServer儲存過程函式
- 儲存過程編寫經驗和優化措施儲存過程優化
- ORACLE PL/SQL 物件、表資料對比功能儲存過程簡單實現OracleSQL物件儲存過程
- Oracle SQL Developer Debug儲存過程OracleSQLDeveloper儲存過程