ABAP程序效率優(yōu)化系列之④——開發(fā)優(yōu)化之?dāng)?shù)據(jù)庫(ST05那些事兒)

ABAP程序效率優(yōu)化系列文章歷史

ABAP程序效率優(yōu)化系列之①——業(yè)務(wù)層面的優(yōu)化

ABAP程序效率優(yōu)化系列之②——開發(fā)優(yōu)化之ABAP時間

ABAP程序效率優(yōu)化系列之③——開發(fā)優(yōu)化之讀取數(shù)據(jù)庫


寫在前面


1招盲、讀取數(shù)據(jù)庫優(yōu)化的這兩篇(上一篇和這一篇),對于HANA來說意義不大,一直在HANA數(shù)據(jù)庫上進行開發(fā)的朋友請忽略

2、本文中的所有例子都是ORACLE數(shù)據(jù)庫上的

3、大家在測試時,如果遇到與我不同的測試結(jié)果,也屬于正撑罨恚現(xiàn)象

4、我的目的是讓大家通過ST05看到SQL的執(zhí)行軌跡菇肃,了解它大概是怎么回事地粪。然后通過HINTS的方式,在執(zhí)行軌跡不符合我們的預(yù)期時琐谤,進行適當(dāng)?shù)母深A(yù)

5蟆技、性能優(yōu)化在運維項目上的作用尤其大,建設(shè)項目的數(shù)據(jù)量小斗忌,復(fù)雜度相對低质礼,難以體會到性能的瓶頸。

初識ST05


首先织阳,我們在一個REPORT程序中編寫一段代碼:

然后打開ST05

接下來按以下步驟操作:

1眶蕉、Activate Trace

2、執(zhí)行REPORT程序

3唧躲、Deactivate Trace

4造挽、Display Trace,然后點執(zhí)行弄痹,可以得到如下的界面

?這個界面展示了SQL的執(zhí)行軌跡:

第二列饭入,是每一條SQL的執(zhí)行時間;

對象名列肛真,是對應(yīng)的表或視圖谐丢;

最后一列,是相應(yīng)的SQL語句蚓让。

初識執(zhí)行計劃


選中上圖中表AFPO OPEN操作的行乾忱,點擊工具欄上的”Explain”按鈕(F9),可以得到SQL的執(zhí)行計劃凭疮。

其中1、2串述、3為SQL執(zhí)行時的執(zhí)行順序执解。

步驟1中的AFPO~2,代表的是AFPO的索引2,該索引包括客戶端和PROJN兩個字段衰腌。

點擊1下面的Access Predicates新蟆,可以看到

即,第一步訪問AFPO表時右蕊,用的就是AFPO~2這個索引琼稻。

步驟2是根據(jù)步驟1得到的ROWID去AFPO獲取數(shù)據(jù),步驟3不用管它饶囚。

多個查詢條件的執(zhí)行計劃


換一段代碼

(在MSEG表中對BUDAT_MKPF新建了索引帕翻,索引名是Z05)

在我目前的項目上,這個SQL在開發(fā)機上執(zhí)行的很快萝风,到了生產(chǎn)機卻執(zhí)行的異常慢嘀掸。通過ST05監(jiān)測其執(zhí)行軌跡,發(fā)現(xiàn)結(jié)果如下:

  • 在開發(fā)機上规惰,第一步是先根據(jù)budat_mkpf?Access睬塌,再根據(jù)werksbwart?filter

  • 在生產(chǎn)機上,第一步是先根據(jù)werksbwart?Access歇万,再根據(jù)budat_mkpf?filter

要解決這個問題并不麻煩揩晴,只需要通過HINTS人工指定索引即可(上一期也提到了),即:

%_HINTS ORACLE ‘INDEX(MSEG “MSEG~Z05”)’贪磺。

(第一個MSEG可以不加引號)

至于生產(chǎn)機為什么和開發(fā)機是不一樣的SQL執(zhí)行計劃硫兰,這個我也不清楚。

據(jù)BASIS解釋說缘挽,是ORACLE的統(tǒng)計分析的結(jié)果瞄崇,導(dǎo)致了這樣的SQL執(zhí)行計劃。

ORACLE認(rèn)為它是最優(yōu)的壕曼,但在執(zhí)行時不一定總是最優(yōu)的苏研。

這時候就需要我們的人工干預(yù),以快速解決這樣的性能問題腮郊。

(一般情況下摹蘑,ORACLE的自動優(yōu)化都是沒太大問題的,但我在這里想說的是轧飞,我們要掌握一個快速解決處理的辦法衅鹿,以備不時之需)

表關(guān)聯(lián)的執(zhí)行計劃


代碼如下

執(zhí)行計劃如下

可以看到,多個表關(guān)聯(lián)時过咬,在圖片最上面的SQL STATEMENT中出現(xiàn)了T_00大渤、T_01,它們是參與JOIN的表的別名掸绞。

因此泵三,在表關(guān)聯(lián)時,指定索引的方式與只查詢一個表時略有不同,格式如下:

%_HINTS ORACLE ‘INDEX(T_00 “MSEG~OIB”)’

進一步分析


在此例中烫幕,大家也可以看到:

第一步俺抽,執(zhí)行的是MSEG~Z11的索引(自建的索引),這個索引包含的內(nèi)容是工廠和移動類型较曼;

第二步磷斧,是按客戶端過濾數(shù)據(jù);

第三步捷犹,執(zhí)行的是MKPF~0這個索引(~0是一個表的主鍵索引)弛饭,它包含的內(nèi)容是MKPF的主鍵字段,因為MSEG和MKPF進行了關(guān)聯(lián)伏恐;

第四步孩哑,是按MKPF的BUDAT過濾數(shù)據(jù)。

(這是我在我的開發(fā)系統(tǒng)的測試結(jié)果翠桦,大家也可以自己測一下這個代碼横蜒,應(yīng)該有很多人跟我是一樣的測試結(jié)果)

我們可以想象,如果數(shù)據(jù)很多的話销凑,我們是根據(jù)工廠和261做第一步更快丛晌,還是根據(jù)一個月的日期做第一步更快?肯定是后者岸酚住澎蛛!

那怎么辦呢?按照上面的方式指定索引嗎蜕窿?加上代碼

%_HINTS ORACLE 'INDEX("T_01" "MKPF~BUD")'

然后試試谋逻,結(jié)果如下:

第一步、第二步?jīng)]有變化桐经,第三步變了毁兆。

沒有達到預(yù)期的希望先ACCESS表MKPF的效果。

那我們把MKPF和MSEG關(guān)聯(lián)的順序顛倒一下可以嗎阴挣?你試過之后發(fā)現(xiàn)依然不行气堕。

怎么辦呢?ORACLE為什么不按我希望的順序執(zhí)行呢畔咧?

于是我開始翻資料茎芭,查找“ORACLE指定查詢順序”的關(guān)鍵字,沒找到原因誓沸,卻最終得到了以下的處理辦法:

?我把MKPF寫在MSEG之前梅桩,并且指定HINTS ordered,使SQL執(zhí)行計劃按表出現(xiàn)的順序執(zhí)行拜隧。

接下來是它的執(zhí)行計劃分析:

OKK薨佟煮寡!這太棒了!犀呼!

這就是我們想要的結(jié)果了!薇组!

案例與實際應(yīng)用


下面這兩個案例外臂,都是我在運維項目上遇到的實際案例。

案例1


SQL語句如下

SELECT

afpo~projn

aufk~auart

afko~aufpl

prps~post1

FROM afpo

INNER JOIN aufk ON aufk~aufnr = afpo~aufnr

INNER JOIN afko ON afko~aufnr = aufk~aufnr

INNER JOIN prps ON prps~pspnr = afpo~projn

WHERE afpo~prps IN (....).

IN的內(nèi)容較小時律胀,執(zhí)行沒有問題宋光,但是超過100條時,ST05的執(zhí)行軌跡如下:

第一步是PRPS的ACCESS

第四步是AUFK的ACCESS?FULL(全表掃描)炭菌,非常耗時

第五步才是AFPO的Z03索引

(Z03是我這里PROJN的索引罪佳,系統(tǒng)中有標(biāo)準(zhǔn)的AFPO~2索引,我也不清楚為什么之前的顧問建了個多余的索引)

(大家如果寫同樣的程序黑低,可能不會遇到跟我同樣的問題)

這個SQL的執(zhí)行速度超慢赘艳,大約5-10分鐘

我一個表一個表的手動查詢克握,都用不了2分鐘的啊蕾管。

分析一下,這個很明顯就是ORACLE自動確定的執(zhí)行順序出了問題(至于怎么)菩暗,所以我就在后面加了ordered的hints掰曾,之后不到2秒鐘,結(jié)果就出來了停团。

案例2


代碼如下

其中GT_ALV中只有一條記錄旷坦,根據(jù)其記錄在PRPS可以找到18條數(shù)據(jù),進而在AFVC中找到4條數(shù)據(jù)佑稠,最后根據(jù)AFVC的4條數(shù)據(jù)查詢COSP的內(nèi)容秒梅。

然而,它在生產(chǎn)系統(tǒng)的執(zhí)行軌跡是這樣的:

它按照順序PRPS-AFVC-COSP的順序執(zhí)行讶坯,但是COSP時卻意外的ACCESS FULL番电,看看嚇人的CPU-Costs和IO-Costs吧,有沒有要解決掉的沖動辆琅?

動手吧漱办,因為它同樣很簡單,指定COSP的索引COSP~1即可(INDEX(T_02 "COSP~1"))婉烟,COSP~1的第一個字段就是OBJNR娩井。

結(jié)果當(dāng)然也是很快的,一瞬間似袁,就查詢出來了洞辣。

寫在最后


利用indexordered這兩個hints咐刨,可能還是無法完全解決我們遇到的問題。除此之外扬霜,hints家族中還有leading(指定首先訪問的表)定鸟、use_nl(nested loop的join方式)、use_hash(hash join的方式)等著瓶。

對于oracle联予,我懂的也不多,這幾個hints怎么用材原,大家還是自己上網(wǎng)了解一下吧沸久,網(wǎng)上的Oracle大神數(shù)不勝數(shù),隨便支點招就夠我們abaper用的了余蟹。


IOS/ANDROID用戶打賞——贊賞碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卷胯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子威酒,更是在濱河造成了極大的恐慌窑睁,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葵孤,死亡現(xiàn)場離奇詭異卵慰,居然都是意外死亡,警方通過查閱死者的電腦和手機佛呻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門裳朋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吓著,你說我怎么就攤上這事鲤嫡。” “怎么了绑莺?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵暖眼,是天一觀的道長。 經(jīng)常有香客問我纺裁,道長诫肠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任欺缘,我火速辦了婚禮栋豫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谚殊。我一直安慰自己丧鸯,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布嫩絮。 她就那樣靜靜地躺著丛肢,像睡著了一般围肥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜂怎,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天穆刻,我揣著相機與錄音,去河邊找鬼杠步。 笑死蛹批,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的篮愉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼差导,長吁一口氣:“原來是場噩夢啊……” “哼试躏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起设褐,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤颠蕴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后助析,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犀被,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年外冀,在試婚紗的時候發(fā)現(xiàn)自己被綠了寡键。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡雪隧,死狀恐怖西轩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情脑沿,我是刑警寧澤藕畔,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站庄拇,受9級特大地震影響注服,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜措近,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一溶弟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞭郑,春花似錦可很、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苇本。三九已至,卻和暖如春菜拓,著一層夾襖步出監(jiān)牢的瞬間瓣窄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工纳鼎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留俺夕,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓贱鄙,卻偏偏與公主長得像劝贸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逗宁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容