国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PLSQL JSON類接口優(yōu)化

IT那活兒 / 377人閱讀
PLSQL JSON類接口優(yōu)化
點擊上方“IT那活兒”公眾號,關注后了解更多內(nèi)容,不管IT什么活兒,干就完了?。?!

事件背景

數(shù)據(jù)庫版本:12.1.0.2
上午還沒到單位,客戶就發(fā)微信告知趕緊到單位處理一個請求慢的問題,原本十幾秒鐘就能完成的請求,現(xiàn)在兩三天跑不完,第一時間想到的可能就是plsql代碼塊中SQL執(zhí)行出現(xiàn)了問題,很有可能是執(zhí)行計劃發(fā)生了改變,到單位上手處理之后,發(fā)現(xiàn)事件沒有自己想的那么簡單,plsql代碼塊中所有的SQL執(zhí)行速度都很快,1s中之內(nèi)就能返回結(jié)果。但是請求確確實實跑了兩三天才完成。
下圖所示中標記的為業(yè)務通過程序記錄的執(zhí)行調(diào)用時間,6000/60/24=4.xx.最慢的時候程序都已經(jīng)跑了四天多。


分析過程

2.1 plsql代碼塊中的相關SQL已經(jīng)進行了排查,并未發(fā)現(xiàn)有什么異常SQL,SQL邏輯很簡單。
查看PLSQL對應的等待事件,這里發(fā)現(xiàn)是db file sequential read(單塊讀),通過對應的p1.p2發(fā)現(xiàn)一直在等待獲取file=63 block=1141320這個數(shù)據(jù)塊,并且根據(jù)下面查詢,發(fā)現(xiàn)對于單個block請求時間長達幾十秒鐘。
2.2 針對對應的等待事件p1.p2,查詢對應的block屬于那個對象,這里我們發(fā)現(xiàn)是CUX_DWMS_CKD_JOB_LOT_IFACE表單塊讀較慢。

因查詢語句太長這里不方便貼出,具體查看語句見如下地址:

https://www.cnblogs.com/hanglinux/p/16302543.html

2.3 分析到這里我懷疑可能是行鏈接或者是行遷移導致的性能問題,通過@$ORACLE_HOME/rdbms/admin/utlchain.sql以及chain.sql對相關問題表進行了分析,并未發(fā)現(xiàn)有行鏈接或者行遷移的情況,并針對表信息進行了查詢以及相關plsql代碼快塊中的執(zhí)行計劃進行了排查。
###行遷移信息:
SQL> @chine
Enter the schema name to check for Row Chaining (RETURN for All): CUX
Enter the table name to check (RETURN for All tables owned by CUX): CUX_DWMS_CKD_JOB_LOT_IFACE
No Chained Rows found in the CUX owned Tables!
###表列相關信息:
###索引相關信息:
###表歷史統(tǒng)計相關信息:
###表段相關信息,這里發(fā)現(xiàn)這個表非常的小,僅僅有3M,對于x8一體機而言即便是循環(huán)嵌套的全表掃描,也不可能這么慢,更何況是走的索引掃描。
###plsql代碼塊中表相關查詢語句以及執(zhí)行計劃如下,執(zhí)行計劃也是相當?shù)暮茫竭@里問題分析不下去了,整整糾結(jié)了一上午。

chain.sql相關腳本地址如下:

https://www.cnblogs.com/hanglinux/p/16302598.html

2.4 通過ash報告獲取當前負載信息
##這里發(fā)現(xiàn)改存儲過程正在慢的點在于apps.json.put
在plsql代碼快中,我們發(fā)現(xiàn)了如下信息,使用json結(jié)構(gòu)構(gòu)造數(shù)據(jù),通過上層查詢的數(shù)據(jù),放入json結(jié)構(gòu)代碼中,然后進程轉(zhuǎn)存,正常情況下都是使用java、python或者其他的開發(fā)工具進行構(gòu)造,因為邏輯都是存儲過程寫的,所以對于構(gòu)造數(shù)據(jù)業(yè)務模塊中都統(tǒng)一使用json結(jié)構(gòu)進行了構(gòu)造,在和開發(fā)的溝通中,我們也定位到plsql執(zhí)行慢的地方在如下代碼塊。
?
2.5 通過對plsql代碼塊進行日志處理,進一步打印每次循環(huán)的時間,每次嵌套大概執(zhí)行的時間是14s。
上述問題表CUX_DWMS_CKD_JOB_LOT_IFACE大概返回2000-3000行數(shù)據(jù),也就是說這個嵌套要執(zhí)行2000-3000次,這里簡單的計算就是大概十幾個小時,但是實際情況下,隨著嵌套循環(huán)的進行,后續(xù)的嵌套會越來越慢,嵌套的執(zhí)行時間也會越來越長,最終導致整個請求在2-3天內(nèi)無法執(zhí)行完畢。
2.6 定位到慢的代碼,進行分析了json結(jié)構(gòu)塊
代碼中的如下部分,每次內(nèi)層嵌套完畢之后,都需要put對如下結(jié)構(gòu)代碼進行覆蓋,結(jié)合ash報告中的TOP PL/SQL Procedures中的信息,我們也是發(fā)現(xiàn)這里的apps.json.put執(zhí)行時間較慢。
l_lotline_json := json();
2.7 問題處理解決
通過以上分析,我們建議將l_lotline_json := json();代碼結(jié)構(gòu)直接放到下層循環(huán)中,每次新建對象,不需要put覆蓋之前的數(shù)據(jù),和業(yè)務人員進行溝通,再次執(zhí)行,請求已經(jīng)恢復到十幾秒內(nèi)完成。
因為自己對于開發(fā)不熟,對于這個問題,專門詢問了開發(fā)的同學,開發(fā)同學如下解釋:按照java的理論新建一個對象消耗的時間更多,如果把l_lotline_json:= json()如下二層嵌套中,每次就需要新建一個對象,不需要put覆蓋之前的數(shù)據(jù)。但在Oracle實際執(zhí)行過程中確確實實是因為put覆蓋對象導致的業(yè)務延遲,原來的業(yè)務執(zhí)行的時候也是沒有問題的,其他的類似業(yè)務也沒有問題,單單對于這個plsql程序出現(xiàn)了情況,這里我也不是很懂。修改后的代碼如下:
這里是修改后的代碼記錄執(zhí)行時間,說明:12號的其他執(zhí)行時間是前臺取消業(yè)務記錄的時間,并未執(zhí)行完畢。



回顧總結(jié)

  • 業(yè)務反饋請求執(zhí)行較慢,通過分析plsql代碼塊SQL執(zhí)行較快;
  • 通過等待事件發(fā)現(xiàn)針對與表CUX_DWMS_CKD_JOB_LOT_IFACE單塊掃描較慢時間長達幾十秒(這里通過結(jié)合plsql代碼塊嵌套執(zhí)行緩慢問題也進一步解釋了為什么單塊讀要執(zhí)行幾十秒,也說明了在循環(huán)嵌套代碼塊中不僅僅是每次嵌套要14s,而是隨著不斷的嵌套循環(huán),執(zhí)行時間會越來越慢。)
  • 通過對應等待事件p1.p2定位問題對象;
  • 分析問題對象有無問題;
  • 通過ash報告定位plsql代碼塊程序接口問題;
  • 結(jié)合開發(fā),通過plsql代碼塊打印log,進一步確定問題;
  • 通過改寫程序代碼,業(yè)務請求執(zhí)行時間由原來的2-3天優(yōu)化至十幾秒。


plsql代碼塊相關分析思路

4.1 統(tǒng)計hash_value那個語句執(zhí)行的多
select t.SQL_HASH_VALUE,t.SQL_ID,count(1) from v$session t 
where t.STATUS=ACTIVE and t.sql_hash_value<>0 and 
t.program not like oracle@c6ogx6a (W% group by  
t.SQL_HASH_VALUE,t.SQL_ID order by 3 desc;
4.2 通過ash_top_plsq定位正在執(zhí)行的子程序
set linesize 120
col entry_package for a25
col entry_procedure for a25
col cur_package for a25
col cur_procedure for a25
col calling_code for a70
select
count(*),
sql_id,
procs1.object_name || decode(procs1.procedure_name,,,.)||
procs1.procedure_name || ||
decode(procs2.object_name,procs1.object_name,,
decode(procs2.object_name,,, => ||procs2.object_name))
||
decode(procs2.procedure_name,procs1.procedure_name,,
decode(procs2.procedure_name,,,null,,.)||procs2.procedure_name)
"calling_code"
from v$active_session_history ash,
all_procedures procs1,
all_procedures procs2
where
ash.PLSQL_ENTRY_OBJECT_ID = procs1.object_id (+)
and ash.PLSQL_ENTRY_SUBPROGRAM_ID = procs1.SUBPROGRAM_ID (+)
and ash.PLSQL_OBJECT_ID = procs2.object_id (+)
and ash.PLSQL_SUBPROGRAM_ID = procs2.SUBPROGRAM_ID (+)
and ash.sample_time > sysdate - &minutes/(60*24)
group by procs1.object_name, procs1.procedure_name,
procs2.object_name, procs2.procedure_name,sql_id
order by count(*)
/
4.3 snapper.sql腳本也可以查詢相關信息

##腳本調(diào)用查詢的其實也是v$active_session_history.PLSQL_ENTRY_OBJECT_ID、PLSQL_ENTRY_OBJECT_ID、PLSQL_SUBPROGRAM_ID相關信息,并不能獲取正在慢的程序接口類的結(jié)構(gòu)。

https://tanelpoder.com

4.4 通過ash報告中的TOP PL/SQL Procedures定位正在慢的程序接口
##這里我通過10046獲取到到相關的內(nèi)部執(zhí)行SQL,但是一些變量值我有點拿不準,也就不貼出來了。觀察Oracle內(nèi)部其實調(diào)用了一個內(nèi)部程序包dbms_ash_internal來獲取的子程序以及具體的程序結(jié)構(gòu)代碼塊

##感興趣的可以看看,記錄在如下地址中:

https://www.cnblogs.com/hanglinux/p/16303325.html

4.5 erp相關plsql優(yōu)化
對于erp系統(tǒng)而言,正常都有一個SQL可以按照請求號,來查詢正在調(diào)用的sid,以及正在執(zhí)行的plsql中的sql_id信息,但有時候也是會出現(xiàn)無法查詢到plsql代碼中具體SQL的尷尬案例。
比如這次分析的案例,通過客戶提供的SQL只能檢查到正在執(zhí)行的plsql代碼sql_id,內(nèi)部的SQL執(zhí)行確確實實找不到,如果發(fā)生此類情況,可能就是正在調(diào)用某個接口或者子程序吧。


本文作者:李行行(上海新炬王翦團隊)

本文來源:“IT那活兒”公眾號

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/129318.html

相關文章

  • Java3y文章目錄導航

    摘要:前言由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 前言 由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關注我的公眾號:Java3y Java3y文章目錄導航 Java基礎 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...

    KevinYan 評論0 收藏0

發(fā)表評論

0條評論

IT那活兒

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<