


摘要 目前采用SAP產(chǎn)品的通常為大型企業(yè),這些企業(yè)的數(shù)據(jù)特點(diǎn)體現(xiàn)為數(shù)據(jù)表多、數(shù)據(jù)量大、數(shù)據(jù)關(guān)系復(fù)雜。有關(guān)技術(shù)人員在二次開(kāi)發(fā)工作中,都無(wú)法避免超大數(shù)據(jù)量的運(yùn)算,而硬件升級(jí)的辦法(比如采用SAP HANA系統(tǒng))則以投資大、周期長(zhǎng)困擾著相關(guān)企業(yè)。本文將以某單位的異常訂單監(jiān)控程序?yàn)槔榻B直接通過(guò)軟件優(yōu)化,高速處理超大數(shù)據(jù)量信息的方法。
【關(guān)鍵詞】SAP ABAP算法優(yōu)化 大批量數(shù)據(jù)處理
1 引言
在信息化系統(tǒng)的深化應(yīng)用過(guò)程中,許多企業(yè)都面臨著如何快速處理海量數(shù)據(jù)的問(wèn)題。以某單位的SAP ERP為例,其財(cái)務(wù)數(shù)據(jù)量以億記,物料、工藝數(shù)據(jù)量以千萬(wàn)記,其它業(yè)務(wù)數(shù)據(jù)量也多以百萬(wàn)記,如果無(wú)法快速地對(duì)這些數(shù)據(jù)進(jìn)行計(jì)算,這些海量數(shù)據(jù)中蘊(yùn)藏的價(jià)值就得不到有效地利用。
SAP公司提供的HANA系統(tǒng)或者其它實(shí)施公司的硬件升級(jí)方案,效果雖然明顯,但成本通常在千萬(wàn)以上、實(shí)施周期以年計(jì)。故本文將以實(shí)例介紹低成本、短周期,依靠軟件優(yōu)化方式快速處理大批量數(shù)據(jù)的方法。
2 背景
2.1 傳統(tǒng)處理大批量數(shù)據(jù)的方法及其局限性
第一種常用處理大批量數(shù)據(jù)的方法是中間表方式。以財(cái)務(wù)月結(jié)為例,如果直接利用原始憑證信息生成月結(jié)表速度將非常緩慢。所以最好的辦法是,每月關(guān)賬時(shí)運(yùn)行后臺(tái)程序(可參考本人論文《利用SAP PORTAL平臺(tái)實(shí)現(xiàn)門(mén)禁信息查詢》第二章),將計(jì)算結(jié)果存入中間表,等到需要月結(jié)或年度報(bào)表時(shí),直接利用中間表生成報(bào)表。這種方法用戶體驗(yàn)好,缺點(diǎn)是時(shí)效性不強(qiáng)。
第二種常用處理大批量數(shù)據(jù)的方法是分批處理。以人力資源的組織結(jié)構(gòu)為例,大型企業(yè)的組織節(jié)點(diǎn)(SAP中將人員也視為組織節(jié)點(diǎn),以便于生成組織樹(shù))達(dá)到幾十萬(wàn)個(gè),生成組織結(jié)構(gòu)圖極其緩慢。于是我們將每個(gè)節(jié)點(diǎn)及其以下三層算作一個(gè)“批次”,首先僅展開(kāi)根節(jié)點(diǎn)及其以下三層,如果用戶雙擊某個(gè)節(jié)點(diǎn),再展開(kāi)這個(gè)節(jié)點(diǎn)下面三層,以此類推。這是因?yàn)橛脩粽嬲榭吹慕M織和人員往往只占所有組織節(jié)點(diǎn)的很小一部分,大量數(shù)據(jù)對(duì)于用戶而言是無(wú)用的,排除無(wú)用數(shù)據(jù)的計(jì)算可以大幅增加數(shù)據(jù)處理速度。
2.2 異常訂單監(jiān)控任務(wù)的特點(diǎn)
某單位的異常訂單監(jiān)控任務(wù),具有四個(gè)特點(diǎn):涉及數(shù)據(jù)龐大、計(jì)算邏輯復(fù)雜、及時(shí)性要求高、無(wú)用數(shù)據(jù)少。這決定了傳統(tǒng)的中間表方法和分批計(jì)算的方法此處并不適用,只能另辟蹊徑。
3 SQL語(yǔ)言優(yōu)化方法
3.1 合理減少連接( JOIN)數(shù)據(jù)表的數(shù)量
如果將所有表格進(jìn)行連接( JOIN),形成的笛卡爾積最高可達(dá)到10^56次方。要加快取數(shù)速度,首先要減少連接表的數(shù)量,一些跟輸入條件沒(méi)有直接關(guān)系的數(shù)據(jù)表,最好排除出主SQL語(yǔ)句,然后另行處理。
本程序的輸入條件包括工廠、訂單類型、分廠、生產(chǎn)訂單、物料號(hào)、WBS號(hào)、工作中心、交貨時(shí)間,與之有關(guān)的表格為AFKO、AFPO、AUFK、AFVC、CRHD、PRPS,
故這6個(gè)表格需要在主SQL語(yǔ)句中互相連接。此時(shí)主SQL的數(shù)據(jù)明顯減少。而其它數(shù)據(jù)表則另行用單獨(dú)的SQL寫(xiě)入各自對(duì)應(yīng)的臨時(shí)內(nèi)表,再通過(guò)READ TABLE方法填入主內(nèi)表(若內(nèi)表鍵值己排序,按鍵值二分法查找速度會(huì)更快)。
另外,如果我們只想用READ TABLE判斷某行數(shù)據(jù)是否存在,而不需要讀取該行數(shù)據(jù),可以在READ TABLE最后增加TRANSPORTING NO FIELDS關(guān)鍵字,進(jìn)行加速。
對(duì)于那些數(shù)據(jù)量大的表(如AFVV含2100多萬(wàn)條數(shù)據(jù),MAKT含200多萬(wàn)條數(shù)據(jù)),直接讀取不僅慢而且占用大量?jī)?nèi)存空間,故需要索引表的協(xié)助。如圖1,我們用索引表ITAB OUTPUT1復(fù)制了主內(nèi)表ITABOUTPUT的數(shù)據(jù)(含有我們需要的數(shù)據(jù)的鍵值),按工藝路線號(hào)( AUFPL)排序,再刪除重復(fù)的工藝路線號(hào),就可以得到工藝路線號(hào)的索引表。
如圖2,我們用索引表ITAB OUTPUT1作為條件,快速?gòu)腁FVV表中讀取需要的工序數(shù)據(jù),而主內(nèi)表則可在循環(huán)中通過(guò)READTABLE快速?gòu)呐R時(shí)內(nèi)表ITAB AFVV中填補(bǔ)上每行的工序數(shù)據(jù)。使用索引表需要注意兩點(diǎn)
(1)索引表為空時(shí),取數(shù)速度反而比普通SQL更慢,所以應(yīng)避免索引表為空;
(2)索引表做“等于”比較時(shí)速度很快,但是做“不等于”比較時(shí),會(huì)讓數(shù)據(jù)庫(kù)各行遍歷比較索引表各行,非常耗時(shí),所以應(yīng)避免“不等于”比較。
另外,出于節(jié)省內(nèi)存空間的考慮,使用完的索引表和臨時(shí)內(nèi)表應(yīng)該及時(shí)清空。
3.2 強(qiáng)化篩選條件
SQL對(duì)數(shù)據(jù)的篩選有兩處,一處為連接( JOIN)后面ON的條件,一處為WHERE條件。前者會(huì)首先執(zhí)行,可以有效避免數(shù)據(jù)表做笛卡爾乘積,但它們的邏輯比較簡(jiǎn)單,通常是鍵值的計(jì)算,很難把邏輯做強(qiáng)。我們通常強(qiáng)化的是后面的WHERE條件。
若僅僅以輸入條件(見(jiàn)2.1節(jié))作為篩選條件,其單次取數(shù)耗時(shí)依然在5分鐘以上。在東電的業(yè)務(wù)中,工作中心數(shù)據(jù)、物料數(shù)據(jù)均跟工廠編號(hào)存在邏輯關(guān)聯(lián)(例如工作中心編碼和分廠編碼存在對(duì)應(yīng)關(guān)系),同時(shí)工序控制碼、訂單類別、項(xiàng)目編號(hào)也可以增加約束條件(例如外協(xié)工序和說(shuō)明工序,就不用考慮報(bào)工的問(wèn)題),故我們可通過(guò)增強(qiáng)篩選條件的方式減少不必要的取數(shù)工作。
如圖3,盡管輸入條件只有8個(gè),但我們底層代碼的篩選條件卻多達(dá)15個(gè),將SQL取數(shù)時(shí)間從5分鐘以上縮減到3秒以內(nèi)。
注意:
(1)篩選條件中應(yīng)避免通配符的使用;
(2)各企業(yè)數(shù)據(jù)規(guī)范不同,故增強(qiáng)篩選條件的方式也會(huì)不同,需要根據(jù)實(shí)際情況進(jìn)行選擇。
3.3 使用游標(biāo)( CURSOR)
SQL語(yǔ)言取數(shù)時(shí)會(huì)將數(shù)據(jù)臨時(shí)存到內(nèi)存的結(jié)果集,而游標(biāo)就是指向結(jié)果集的指針。本身逐行操作是慢于普通SQL的,但是由于SAP的內(nèi)存管理機(jī)制,特定情況下游標(biāo)反而體現(xiàn)出性能優(yōu)勢(shì)。
一旦物理內(nèi)存不足,SAP系統(tǒng)會(huì)向SWAP請(qǐng)求擴(kuò)展空間,此時(shí)運(yùn)算會(huì)變得很慢。如果連擴(kuò)展空間都不足,則會(huì)報(bào)內(nèi)存錯(cuò)誤,甚至無(wú)法正常取數(shù)。游標(biāo)在這時(shí)不僅能保證取數(shù)正常,還快于一般的SQL。如圖4所示。
注意:
(1)只有數(shù)據(jù)量特別大而篩選條件較少時(shí),顯式游標(biāo)的性能優(yōu)勢(shì)才能體現(xiàn)出來(lái);
(2) -般情況應(yīng)避免使用游標(biāo);
(3)游標(biāo)使用后需要關(guān)閉,否則會(huì)內(nèi)存泄漏。
3.4 使用提示( HINTS)
ABAP語(yǔ)言也支持在SQL中使用提示(HINTS),我們可以通過(guò)提示設(shè)定檢索數(shù)據(jù)表的索引、連接順序、索引表、SQL執(zhí)行方式等工作。
通過(guò)事務(wù)代碼sell表找到需要優(yōu)化的數(shù)據(jù)表,通過(guò)轉(zhuǎn)到.>索引即可創(chuàng)建或管理該數(shù)據(jù)表的提示索引。圖5例子中,我們?yōu)榱硕?jí)成本核算在CSKS表增加了Z01索引,在SQL語(yǔ)句的FROM后增加“%HINTSORACLE'INDEX(”CSKS””CSKS~Z01”)”,就可以用Z01中的字段代替鍵值進(jìn)行檢索,從而加速。
注意:索引的設(shè)計(jì)非常依賴各個(gè)業(yè)務(wù)單位的數(shù)據(jù)規(guī)范和技術(shù)人員的個(gè)人經(jīng)驗(yàn),所以一般不推薦使用。
4 針對(duì)邏輯代碼的優(yōu)化
4.1 避免遞歸和多重循環(huán)
在對(duì)SQL語(yǔ)言進(jìn)行優(yōu)化后,我們獲得的主內(nèi)表數(shù)據(jù)從25萬(wàn)行縮減到了10萬(wàn)行。雖然主內(nèi)表的行數(shù)明顯減少,但是要快速處理這些數(shù)據(jù),依然不得不對(duì)邏輯代碼進(jìn)行優(yōu)化。傳統(tǒng)上軟件工程師用遞歸或多重循環(huán)的方式處理聯(lián)合訂單,我根據(jù)業(yè)務(wù)邏輯設(shè)計(jì)了用標(biāo)志位代替遞歸和多重循環(huán)的算法。
我們將訂單狀態(tài)和工序狀態(tài),抽象為了4個(gè)類型,當(dāng)我們按訂單號(hào)從大到小排列時(shí),循環(huán)就會(huì)按照從上層到下層的順序遍歷這些訂單行,并標(biāo)記其訂單狀態(tài)、工序狀態(tài)、子訂單狀態(tài)、子工序狀態(tài)。而我又將錯(cuò)誤類型抽象為5個(gè)類型,并列出了狀態(tài)與錯(cuò)誤類型的對(duì)應(yīng)關(guān)系。
根據(jù)狀態(tài)與錯(cuò)誤的對(duì)照關(guān)系,我們可以有效判斷各行是否出錯(cuò),出錯(cuò)類型是什么。我們對(duì)數(shù)據(jù)的判斷和分類,只需要一次循環(huán)加一些READ TABLE操作即可完成。使用標(biāo)志位還有兩個(gè)優(yōu)點(diǎn):
(1)編號(hào)有擴(kuò)展性,可適應(yīng)追加需求;
(2)當(dāng)標(biāo)志位滿足不進(jìn)行后續(xù)計(jì)算的條件時(shí),就可以直接省略后續(xù)計(jì)算。
根據(jù)不同的業(yè)務(wù)邏輯,工程師可以采用不同方式回避遞歸和多重循環(huán)的存在。標(biāo)志位這種方式與控制工程的原理類似,是適用性比較廣的方式。
4.2 使用字段符號(hào)( FIELD-SYMBOLS)
ABAP循環(huán)默認(rèn)使用工作區(qū)指向循環(huán)的各行,工作區(qū)是單獨(dú)開(kāi)辟的內(nèi)存地址。如果我們修改各行數(shù)據(jù),需要先修改工作區(qū),然后再通過(guò)邏輯條件尋址,再修改內(nèi)表所處的內(nèi)存地址,一旦內(nèi)表過(guò)大,這種計(jì)算方式就會(huì)非常緩慢。字段符號(hào)(FIELD-SYMBOLS)是直接指向內(nèi)表各行的指針,允許我們直接修改內(nèi)表以節(jié)省尋址時(shí)間。如圖6所示。
4.3 謹(jǐn)慎使用刪除和修改操作
ABAP中對(duì)內(nèi)表進(jìn)行刪除(DELETE)和修改( MODIFY)操作,使用WHERE語(yǔ)句作為判定條件,其原理是遍歷內(nèi)表,找到符合條件的行,再進(jìn)行操作。因?yàn)樾枰闅v內(nèi)表,在內(nèi)表特別龐大時(shí)這種操作極其緩慢。對(duì)于這類操作,第一是盡量不使用,第二是必須使用時(shí)盡量在循環(huán)外使用,第三是必須在循環(huán)內(nèi)使用時(shí)應(yīng)使用索引(INDEX)而不是判定條件。
對(duì)于刪除操作,可以先在循環(huán)時(shí)將要?jiǎng)h除的行做好標(biāo)記,然后再在循環(huán)外統(tǒng)一刪除。在圖7中,我就是在循環(huán)外統(tǒng)一刪除了DESCRIPT__ NO為-l(即需要?jiǎng)h除的標(biāo)記)的所有行。這樣也便于計(jì)算行序,因?yàn)锳BAP中每次刪除操作后,行序都會(huì)重新置O,不利于使用索引進(jìn)行定位。對(duì)于修改操作來(lái)說(shuō),可使用字段符號(hào)(見(jiàn)4 2節(jié))避免大部分有關(guān)操作。
對(duì)于不得不在循環(huán)中使用的刪除或者修改操作,需要使用索引。在圖8中,我們利用INDEX關(guān)鍵字,直接用索引找到內(nèi)表的對(duì)應(yīng)行進(jìn)行修改,避免了復(fù)雜的匹配運(yùn)算。另外,我們可以利用TRANSPORTING語(yǔ)句限制要修改的數(shù)據(jù)有哪些,也可以加快計(jì)算速度。
4.4 字符串計(jì)算優(yōu)化
訂單狀態(tài)和工序狀態(tài),本質(zhì)是多個(gè)狀態(tài)構(gòu)成的字符串,所以這類程序必然涉及到字符串計(jì)算。合理使用&&計(jì)算代替拼接( CONCATENATE)計(jì)算,使用CS、NS等基礎(chǔ)計(jì)算代替分割( SPLIT)和尋找(FIND)計(jì)算,都可以有效地進(jìn)行計(jì)算加速。
比如,當(dāng)我判斷訂單狀態(tài)是否包含是否為交貨(DLV)時(shí),需要判定訂單狀態(tài)字符串是否包含“DLV”這個(gè)狀態(tài)。傳統(tǒng)做法是用空格分割字符串再分別比較,或者遍歷字符串尋找“DLV”狀態(tài)。而優(yōu)化算法的偽代碼可寫(xiě)成“IFSTTXT CS 'DLW AND STTXT NS 'PDLW'(即當(dāng)前狀態(tài)文本包含DLV字符串但不含PDLV字符串),速度會(huì)比分割比較或者遍歷尋找快得多。
需要注意的是,ABAP語(yǔ)言在進(jìn)行字符和數(shù)字之間的計(jì)算時(shí),會(huì)在底層進(jìn)行格式轉(zhuǎn)換計(jì)算,速度是比較慢的。故設(shè)計(jì)程序時(shí)最好避免字符和數(shù)字間的運(yùn)算。
5 輔助工具
如圖9所示,若程序員無(wú)法憑借經(jīng)驗(yàn)判斷程序哪個(gè)節(jié)點(diǎn)比較耗時(shí),則可借助SAP自帶的程序運(yùn)行時(shí)間分析工具(事務(wù)代碼se30),該工具可以協(xié)助程序員看到各個(gè)節(jié)點(diǎn)的耗時(shí)和耗時(shí)比重;若程序員希望看到數(shù)據(jù)庫(kù)操作的細(xì)節(jié)性能,則可以使用事務(wù)代碼ST05追溯SQL的運(yùn)行軌跡。通過(guò)對(duì)程序各部分執(zhí)行效率的分析,我們就可以采取有針對(duì)性的優(yōu)化。
此外,ABAP語(yǔ)言提供了“GET RUNTIME FIELD tl”(tl為程序員定義的整型變量)這種語(yǔ)句,該語(yǔ)句可獲取程序當(dāng)前時(shí)間(時(shí)間單位為微秒)。程序員可以在不同位置安插該語(yǔ)句,然后通過(guò)獲取的時(shí)間差值來(lái)評(píng)估程序的效率。
6 結(jié)語(yǔ)
異常訂單監(jiān)控程序在優(yōu)化前運(yùn)行時(shí)間超過(guò)36分鐘,而在優(yōu)化后運(yùn)行時(shí)間壓縮到5分鐘左右,對(duì)于用戶體驗(yàn)提升巨大。技術(shù)人員可以根據(jù)情況選擇本文的算法優(yōu)化或2.1節(jié)介紹的方法高速處理大批量數(shù)據(jù)。在提升系統(tǒng)效率、挖掘數(shù)據(jù)資源方面,軟件優(yōu)化的方法跟硬件升級(jí)的方法一樣,都是可行且有效的。
參考文獻(xiàn)
[1]兔寶.SAP ABAP游標(biāo)的使用(示例)[OL] http://blog. csdn. net/szlaptop/article/details/8565285.
[2] Twilight.ABAP MODIFY語(yǔ)句如何高性能修改內(nèi)表中多條數(shù)據(jù)[OL].http://bbs.sapclub. cc/thread-490-1-1. html.
[3]王建文.利用SAP PORTAL平臺(tái)實(shí)現(xiàn)門(mén)禁信息查詢[J].中國(guó)管理信息化,2016,19 (01).