關於自定義程式的效能最佳化

qiujun發表於2008-07-18

關於自定義程式的效能最佳化
說明:本文件是參照sap程式最佳化標準培訓教材BC490。
程式最佳化宗旨:1.正確運用索引,儘量避免以全表掃描的方式提取資料,
這是程式效能的最主要影響因素。
2.儘量減少資料的傳輸(例如,利用buffer,無用列不要傳,資料
的過濾儘量放在資料庫層等)。
3.批處理優於逐筆處理。
4.讓程式碼少作無用功,擯棄無用程式程式碼。

一、實現方式的最佳化:
1.檢查系統標準報表,察看有沒有功能相同,相似的報表,以標準報表,或標準報表的增強版代替自定義開發程式。
2.低效率的query程式,如果問題出在無法最佳化的infoset 則應該考慮abap開發。
3.透過資訊結構產生的查詢程式,要特別注意效能,必要的時候考慮abap自定義開發,或query, report painter 等方式實現。
4.透過邏輯資料庫實現的程式,如果效能低,可以考慮abap開發實現。

二、執行方式的最佳化:
1.對於非實時資料查詢報表,可以考慮放到後臺執行。
2.非實時資料查詢,可以透過自定資料表儲存運算結果,讓使用者直接從自定義表抽取報表資料,大大提升查詢響應速度。
3.定期後臺執行程式,把結果存入文件直接讓使用者下載等。

三、查詢介面的最佳化:
1. 注意避免完全無輸入限制的介面,這樣可能會導致全表掃描的查詢方式,帶來效能問題
2.查詢介面的設計要儘量契合程式中SQL的where條件。

四、程式程式碼的最佳化:
1) 正確運用索引:For all frequently used Select statements, try to use an
index. You always use an index if you specify (a generic part of)
the index fields concatenated with logical Ands in the Select
statement's Where clause. Note that complex Where clauses
are poison for the statement optimizer in any database system。
如果一個大資料量的SQL查詢,WHERE條件沒有利用索引提取資料,必然帶來嚴重的效能問題:可以透過工具ST05等分析查詢效能,或直接透過觀察法分析SQL查詢語句。
A.首先檢視是否使用正確的資料表,(例如如果要取得科目期間金額資料,可直接從glt0表中獲得,而不要透過bseg累加計算了)。
B.如果當前表不能提供按索引查詢,可考慮是否可以透過索引表,例如vbrp中沒有按物料的條件查詢,但vbrmp則有按物料的索引,可以透過該表獲得憑證號,再透過憑證號到VBRP中獲得所需資訊。
C.看有沒有符合條件的檢視。
D.按查詢條件建立索引。

*自定義索引請注意以下問題:
1.不要修改標準索引。
2.每個表一般索引個數不要超過5個,索引欄位一般不要超過4個。
3.儘量不要在主資料表和業務資料表中新增索引。
4.不要在以DD打頭的標中建索引,因為他們是基礎表。
5.欄位排列按一下規則: Identifiers:+ Organizational units:+ Status fields:+ Classifiers:+ Date and time:+ Text fields:)。
6.對於非常複雜的where條件要拆成多查詢語句,因為資料庫的查詢最佳化器無法對複雜條
件查詢實現最佳化,可能導致非索引查詢。
2) Where條件中儘量不要用“非”的查詢條件(諸如not,<>, not in ,etc),這樣可以縮小
資料搜尋範圍。
3)注意BUFFER:For all frequently used, read-only tables, try to use SAP buffering.
Network load is considerably less。
4) 儘量避免巢狀查詢,多SQL查詢,看可不可以用檢視,表關聯或子查詢替代。
5) 用Select Into Table 代替Select + Append模式語句。
6) 用批處理模式代替逐紀錄處理,例如:
INSERT CUSTOMERS FROM TABLE TAB.
比下面語句要高效的多
LOOP AT TAB INTO TAB_WA.
INSERT INTO CUSTOMERS VALUES TAB_WA.
ENDLOOP.
其他操作原理相同
7) 把運算儘量放到SQL層次實現,避免不必要資料的傳輸,例如
SELECT * FROM SBOOK INTO SBOOK_WA
WHERE CARRID = 'LH' AND CONNID = '0400'.
ENDSELECT.
比下面語句要高效率
SELECT * FROM SBOOK INTO SBOOK_WA.
CHECK: SBOOK_WA-CARRID = 'LH' AND SBOOK_WA-CONNID = '0400'.
ENDSELECT.

還有: DATA: MAX_MSGNR type t100-msgnr.
SELECT MAX( MSGNR ) FROM T100 INTO max_msgnr
WHERE SPRSL = 'D' AND
ARBGB = '00'.比下面語句要高效率得多
DATA: MAX_MSGNR type t100-msgnr.
MAX_MSGNR = '000'.
SELECT * FROM T100 INTO T100_WA
WHERE SPRSL = 'D' AND
ARBGB = '00'.
CHECK: T100_WA-MSGNR > MAX_MSGNR.
MAX_MSGNR = T100_WA-MSGNR.
ENDSELECT.
等等,其他操作原理相同。
8)不要濫用 SELECT *,一般應把所需欄位list出來,不要list不必要的欄位,減少資料傳輸,減輕網路負擔,提升效能。

9)大資料量內表處理的最佳化
a.批處理優於逐紀錄處理,例如APPEND LINES OF ITAB1 TO ITAB2.
優於
LOOP AT ITAB1 INTO WA.
APPEND WA TO ITAB2.
ENDLOOP.
ITAB2[] = ITAB1[].
優於
REFRESH ITAB2.
LOOP AT ITAB1 INTO WA.
APPEND WA TO ITAB2.
ENDLOOP.

b.運用排序和BINARY SEARCH
If internal tables are assumed to have many (>20) entries, a linear
search through all entries is very time-consuming.
Try to keep the table ordered and use binary search
or used a table of type SORTED TABLE.
If TAB has n entries, linear search runs in O( n ) time, whereas
binary search takes only O( log2( n ) ).
例如:
READ TABLE ITAB INTO WA WITH KEY K = 'X' BINARY SEARCH.
遠優於
READ TABLE ITAB INTO WA WITH KEY K = 'X'.

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/90072/viewspace-1007469/,如需轉載,請註明出處,否則將追究法律責任。

相關文章