一次sql優化小記
問題提出:某一應用db伺服器遷移到idc後,總部基礎資料同步到這臺db上整個同步耗時在4個小時以上,使用者難以接受,觀察到這個現象後,即著手對同步基礎資料的儲存過程做優化調整,下面的調整優化以同步中的某一個大表ka_detail為例,列出優化的步驟和方法,最終的調整結果:過程執行時間由2個小時以上,優化為現在的30秒左右。記錄文件,供參考。
檢查同步過程,發現因業務系統的限制,同步時間主要消耗在本地table和通過dblink的遠端table的delete,update,insert上,此外遠端table上有trigger,也是一個因素;整個同步時間耗時過長,和資料倉儲db每天的停機冷備份衝突,最終可能會導致基礎資料還沒有同步結束的時候,資料倉儲db停機做冷備份,進而導致同步過程失敗,影響下游系統的作業。
一:檢視當前狀況下同步ka單店過程執行的時間
14:10:44 SQL> exec syn_fenxiao_ka_detail;
start syn_fenxiao_ka_detail time0 is:20071219 14:14:09
start syn_fenxiao_ka_detail time1 is:20071219 14:14:11
insert and update of ka_detail synchronize is unsuccessful!!!-0008-SUG0632
begin syn_fenxiao_ka_detail_before; end;
ORA-01013: user requested cancel of current operation
16:38:34 SQL>
同步過程exec syn_fenxiao_ka_detail 執行了2個多小時還沒有完成,手工停止。
二:第一次優化過程,用merge語句代替insert,update 語句
檢視ka_detail 表的記錄數
SQL> select count(*) from ka_detail;
COUNT(*)
----------
11822
該表有近12000筆記錄,為基礎資料中最大的一個表。分析同步該表的過程syn_fenxiao_ka_detail ,過程中的update和insert語句可以用merge 語句代替,只需要一次全表掃描,將會較大程度的提高過程的執行效果(oracle 9i 新增的merge 語句,對於資料倉儲中經常用的資料批量匯入更新,可以較好的提高sql語句的效率),過程修改後的執行情況如下
10:48:53 SQL> exec syn_fenxiao_ka_detail;
start syn_fenxiao_ka_detail time0 is:20071219 10:52:23
start syn_fenxiao_ka_detail time1 is:20071219 11:29:48
start syn_fenxiao_ka_detail time2 is:20071219 11:29:55
start syn_fenxiao_ka_detail time2 is:20071219 11:29:55
syn_fenxiao_ka_detail synchronize successful!!!
可以看到,第一次優化後的執行時間將在40分鐘左右,過程的執行效果有了很大提高
三:第二次優化過程
再次分析過程syn_fenxiao_ka_detail,對程式進行分段測試,確定40分鐘的耗時在每個子程式段的分佈情況(可以採用分段測試,增加dbms_output.put_line,來確定過程執行的瓶頸正在那個子程式段上,或者利用作業系統的topas/top,結合v$session,v$process,v$sqltext ,可以確定耗用資源最多的,佔用時間最長的sql語句,對此語句進行優化)。
start syn_fenxiao_ka_detail time0 is:20071219 10:52:23
start syn_fenxiao_ka_detail time1 is:20071219 11:29:48
觀察上面的測試輸出,找到對應的程式段,可以發現執行時間絕大部分為delete語句。
找到對應的語句,分析該語句的執行計劃和統計資訊,如下
SQL> delete ka_detail@lfxpub a where not Exists
2 (select 'x' from ka_detail b where a.ka_detail=b.ka_detail);
已刪除0行。
統計資訊
----------------------------------------------------------
23628 recursive calls
0 db block gets
23624 consistent gets
0 physical reads
0 redo size
518 bytes sent via SQL*Net to client
394 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
0 rows processed
consisten read 非常大,這麼大的邏輯讀是造成同步耗時的主要原因,應考慮優化(需要參考sql的執行計劃)。最終優化後的語句的執行計劃和統計資訊如下
SQL> delete ka_detail@lfxpub where ka_detail in
2 (
3 select ka_detail from ka_detail@lfxpub
4 minus
5 select ka_detail from ka_detail
6 );
已刪除0行。
統計資訊
----------------------------------------------------------
6 recursive calls
0 db block gets
93 consistent gets
0 physical reads
0 redo size
532 bytes sent via SQL*Net to client
414 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
0 rows processed
可以看到,優化後sql的consisten read 降低了大概200倍,效率有了極大提高。
至此,表ka_detail的同步過程優化結束,其他過程,亦可參照處理。
SQL> set serveroutput on;
SQL> set time on;
14:24:59 SQL> exec syn_pesd_ka_detail;
insert and update of ka_detail synchronize successful!!!
PL/SQL procedure successfully completed
14:25:31 SQL>
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10159839/viewspace-149075/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 記一次sql優化SQL優化
- 記一次卓有成效的SQL優化SQL優化
- 記一次優化ansible inventory的小例子優化
- 記一次UITableView優化UIView優化
- SQL優化筆記SQL優化筆記
- 記錄一次SQL函式和優化的問題SQL函式優化
- 記一次SQL Server刪除SQL調優SQLServer
- 記一次SQL調優過程SQL
- ? 記一次前端效能優化前端優化
- 記一次分頁優化優化
- 記錄一次打包優化優化
- Oracle Sql優化筆記OracleSQL優化筆記
- 一次sql語句優化的反思SQL優化
- 記一次 T-SQL 查詢優化 索引的重要性SQL優化索引
- 記一次 Webpack 專案優化Web優化
- 記一次Elasticsearch優化總結Elasticsearch優化
- 記一次golang的gzip優化Golang優化
- 記一次效能優化經歷優化
- 記一個SQL優化案例SQL優化
- SQL優化筆記 [final]SQL優化筆記
- 涉及子查詢sql的一次優化SQL優化
- 關於SQL優化的小知識SQL優化
- 記一次 spinor flash 讀速度優化優化
- 記一次公司產品「負」優化優化
- 記一次Node專案的優化優化
- 記MySQL一次關於In的優化MySql優化
- 記一次前端效能優化的案例前端優化
- 一次非常有趣的 SQL 優化經歷SQL優化
- 一次非常有趣的sql優化經歷SQL優化
- 慢SQL優化實戰筆記SQL優化筆記
- Vue SPA專案優化小記Vue優化
- 漫漫優化路,總會錯幾步(記一次介面優化)優化
- 讀小程式效能優優化實踐-筆記優化筆記
- SQL Server一次SQL調優案例SQLServer
- 記一次 VUE 專案優化實踐Vue優化
- 記一次Prometheus代理效能優化問題Prometheus優化
- 記一次提升18倍的效能優化優化
- NOT IN 一次優化優化