ABAP程序運行效率

程序的效率是每個程序員都應該重視的,無論您是採用哪一種語言進行開發. 程序有時候越短,並不

一定越快,有時候程序很多代碼,但不一定會很慢. 性能是一把雙刃劍, 獲得時間效率的同時, 犧牲

的是空間的開銷. 這裏提供一些建議以提高你的程序運行速度和減低系統荷載。

首先是儘量減少I/O操作,類似對硬盤的讀寫的I/O操作是最耗費時間的, 比如讀寫數據庫。以下是

減少I/O操作的例子:

1, 減少數據庫DB的讀寫操作, 當使用VIEW視圖的時候, 當被視圖join的table有數據更新操作的時

候, 同時系統也會更新到這個view裏面, 使得它們之間的數據一樣, 所以使用視圖會對這些日常操

作帶來效率問題. 如果視圖join的表多數是日常事物需要更新的事物數據表(如EKET), 就要避免

使用視圖.

2, 避免使用SELECT *, 儘量使用SELECT A B C INTO TABLE ITAB這樣的語句。這個操作會將所有符

合條件的數據一次性地讀進內表,這比在SELECT A B C INTO WA... APPEND... ENDSELECT的循環中

添加數據到內表要快。不用頻繁的讀DB.

3, 避免頻繁使用SELECT SINGLE語句, 特別是在LOOP和SELECT...ENDSELECT裏面用, 應該把要讀取

的數據用SELECT FOR ALL ENTRIES IN 一次全部取得, 然後用READ TABLE WITH KEY ... BINARY

SEARCH.

雖然說操作內存比磁盤操作要高效,但是如果對內存的使用不加以控制,可能有些時候不得不對硬盤

的交換空間操作, 這樣就增加了對磁盤的I/O讀寫操作.正如下面所說:

4, 當你定義內表的時候可以也會出現這樣的問題, 比如你定義一個內表使用的是OCCURS 100,而不

是OCCURS 0, 會導致內表長度大於100的時候,就會佔用系統頁面緩存。

5, Field-groups對於多層次的排序和顯示是非常有用的。它是將數據寫入系統的頁面文件,而不是

內存(內表一般是使用內存的)。基於這個原因,field-groups比較適合於處理大量數據的列表(

一般超過50000條記錄)。如果涉及大量的數據處理,應該首先和系統管理員協商來決定這個程序最

多能使用多少內存,以計算這個程序需要使用多少資源。然後你就可以決定是把數據寫入內存還是

交換空間。

6, 用SORT代替ORDER BY, ORDER BY從句是執行在數據庫服務器上, 而SORT是ABAP語句執行在應用服

務器上的. 數據庫服務器通常會形成性能瓶頸問題, 所以最好是吧數據導入內表做SORT.

7, 避免使用SELECT DISTINCT語句, 因爲當你用來判斷唯一的字段爲非索引字段時, 效率是十分的

低, 所以請導入內表SORT後, 使用DELETE ADJACENT DUPLICATES 來去重複.

其次就是要減輕CPU的負載, 可以通過優化程序來改善,比如在程序中語句和算法, 以下是減低CPU

負載的優化例子:

1, 使用宏代替頻繁函數調用. ABAP沒有內聯函數這個說法, 所以我們如果需要頻繁調用函數時, 函

數調用有棧內存創建和釋放的開銷. 在ABAP中可以用宏代碼提高執行效率,宏代碼不是函數但使用

起來像函數,編譯器用複製宏代碼的方式取代函數調用,省去了參數壓棧、從而提高速度。注意使

用宏有缺點:(1)容易出錯, 宏不能pass-by-value按值傳遞,用於代替實現函數功能時要十分注意

!(2)不可調試; (3)無法操作類的私有數據成員.

2, 避免使用過得的LOOP 和SELECT .... END SELECT. 避免使用嵌套的LOOP 和SELECT .... END

SELECT.

3, 儘可能多地使用表的KEY FIELD作爲Where分句的條件選項。比如SELECT * FROM BSEG WHERE

BUKRS = '1000' AND BELNR = '0100000007' AND GJAHR =

'2006' AND BUZEI = '003'. 這裏的四個字段BUKRS,BELNR,GJAHR,BUZEI 都

是BSEG表的KEY字段.

4, 如果某些數據需要頻繁的從不同表提取, 使用視圖VIEW實現讀取緩存可以提高效率. 當視圖連接

的是讀取次數較多, 但寫入不頻繁的表時(比如物料主數據表MARA), 可以使用視圖, 這樣比在程序

裏面簡單用join要快,理論上join語句每次讀取的速度都是一樣的, 而視圖是從讀二次開始就快了,

而且cache使得網絡負載減低.

5, 使用SQL語句裏面的JOIN時候, 應該避免JOIN的表不要超過3個, 否則嚴重影響效率. 如果真的要

JOIN表3個以上的話, 正確的方法不是用視圖VIEW, 而是使用SELECT ... INTO TABLE ... FOR ALL

ENTRIES IN 以及 READ TABLE WITH KEY BINARY SEARCH.例如我們要提高讀取BSEG表的性能,首先我

們會根據GJAHR主鍵從BKPF表取出部分數據到內表itab,然後使用FOR ALL ENTRIES IN itab WHERE

BSEG~BELNR = itab~BELNR 這樣的的方法取得符合itab裏所有條件的BSEG數據.注意使用FOR ALL

ENTRIES要先CHECK作爲條件的內表itab是否爲空,還有作爲WHERE的條件在這個內表裏面是否會有空

值存在,否則無效.

6, 注意使用CORRESPONDING FIELDS OF 和  MOVE-CORRESPONDING 時候會進行字段比較, 帶來CPU的

開銷大.

7, 避免過得而頻繁的數據類型轉換,比如N轉換爲C,但是從N轉換成STRING卻是很快的,因爲操作

STRING比CHAR類型少了比較長度的時間.

8, 使用二級索引提高DDIC的讀寫效率, 可以根據你的需要在SE11裏面創建INDEX, 並讓你程序裏的

SQL查詢語句裏WHERE條件的順序與你的索引順序一致.

9, 二分查找比線性查找要高效,READ TABLE的之前使用SORT TABLE BY XXX 某個表關鍵字段進行排

序, 然後使用READ TABLE WITH KEY XXX = 'XXX' BINARY SEARCH. 這個就是所謂的二分

查找法的應用.

10, 避免使用SQL語句動態查詢條件,動態表名和動態字段名, 必要時候用宏或者子程序模塊代替.

11, 對於同一功能的函數和方法, 調用METHOD比調用FUNCTION要快.

12, SORTED TABLE可以使用二分查找法取得節點, 其時間複雜度是O(log N),但是插入節點會慢,因

爲要移動很多節點. 而HASHED TABLE則是基於哈希算法的,其高效主要體現在把數據的存儲和查找時

間大大降低,幾乎可以看成是常數時間O(1),而代價是消耗比較多的內存,然而在硬件技術越來越

發達的今天,用空間換時間的做法在某種意義上是值得的。但是使用哈希表必須注意鍵值的唯一性

!如果鍵值會出現重複的話, 不能使用哈希表,只能用排序表和標準表。

13, 使用APPEND LINES(或者INSERT LINES) OF ITAB1 TO ITAB2 比 LOOP AT ITAB1 INTO WA.

APPEND(INSERT) WA TO ITAB2. ENDLOOP. 要高效.

14, 使用效率比較高的COLLECT, DELETE ADJACENT DUPLICATES FROM語句。

15, 使用高效的CONTEXT SQL語句.如以下代碼2比代碼1要快10倍以上!

代碼1:

SELECT * FROM SBOOK INTO SBOOK_WA UP TO 10 ROWS.
  SELECT SINGLE AIRPFROM AIRPTO INTO (AP1, AP2)
         FROM  SPFLI
         WHERE CARRID = SBOOK_WA-CARRID
         AND   CONNID = SBOOK_WA-CONNID.
  SELECT SINGLE NAME INTO NAME1 FROM  SAIRPORT
         WHERE ID = AP1.
  SELECT SINGLE NAME INTO NAME2 FROM  SAIRPORT
         WHERE ID = AP2.
ENDSELECT.

 

代碼2:

SELECT * FROM SBOOK INTO SBOOK_WA UP TO 10 ROWS.
  SUPPLY CARRID = SBOOK_WA-CARRID
         CONNID = SBOOK_WA-CONNID
             TO CONTEXT TRAV1.
  DEMAND AIRPFROM   = AP1
         AIRPTO     = AP2
         NAME_FROM  = NAME1
         NAME_TO    = NAME2
             FROM CONTEXT TRAV1.
ENDSELECT.

 

最後是注意內存的使用,以下是內存優化方面的例子:

1, 雖然ABAP擁有垃圾處理的機制, 但是這個是在程序運行完成後實現的. 所以我們儘量把無用的變

量,內表,對象都釋放掉;

2, 儘量減少無用的靜態定義的變量,內表和對象, 因爲靜態定義的對象會在編譯開始就佔有內存空

間;

3, 儘量減少網絡的傳輸負載, 比如在設計RFC遠程調用傳回的內表數據要儘量精簡, 數據量越大,對

CPU和內存需求越多;

4, 內存使用緊張的情況下, 使用FREE語句, 以及SQL語句的PACKAGE SIZE n 選項.

SELECT vbeln erdat
FROM vbak
INTO TABLE li_vbak PACKAGE SIZE 50.

發佈了9 篇原創文章 · 獲贊 5 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章