在上一篇博客《如何減少DB的訪問次數?》中談到,爲提升程序性能,在ABAP編程過程中應儘量減少DB的訪問次數。與此同時,在訪問DB時還應儘量減小在與DB交互的數據量,這樣可減小DB通信的網絡負擔,提升訪問速度。
性能優化是一件錙銖必較的工作,在本篇博客中,讓我們一起看下使用ABAP時,可以通過哪些方式達到“減少DB交互數據量”的目標。
方式1: 避免 SELECT *
這一點很好理解,也就是在搜索時,顯性指定所需的字段。儘量避免返回不必要的數據,因爲任何一個字段的選取,DB都會進行相關的遍歷查找,與DB交互時應儘量將數據遍歷時間降到最低。
不要圖方便使用SELECT * FROM sflight INTO CORRESPONDING FIELD 這樣的語句。
方式2:使用WHERE語句限定搜索範圍
這一點不做過多解釋,合理地使用WHERE語句是任何一種編程語言的通用規範。
方式3:避免在SELECT … ENDSELECT中使用CHECK等類似的判斷語句
原因同第二點,合理地通過WHERE限定數據集,僅選取有效的數據進行處理;而非在選取後,再判斷數據的有效性。
方式4:使用UP TO n ROWS來限定結果集數目
使用UP TO n ROWS特別適用於選取特定條件、特定數目的SELECT。看下面的例子,從DB中選取10位折扣最大的客戶,應直接使用UP TO 10 ROWS, 而非每一次手動計數。
DATA: ls_scustom TYPE scustom,
lt_scustom TYPE TABLE OF scustom WITH EMPTY KEY.
* -- Bad --*
SELECT id name discount
FROM scustom
INTO (ls_scustom-id, ls_scustom-name, ls_scustom-discount)
WHERE custtype = 'B'
ORDER BY discount DESCENDING.
IF sy-dbcnt > 10.
EXIT.
ENDIF.
WRITE:/ ls_scustom-id, ls_scustom-name, ls_scustom-discount.
ENDSELECT.
* -- Good --*
SELECT id name discount
FROM scustom UP TO 10 ROWS
INTO CORRESPONDING FIELDS OF TABLE lt_scustom
WHERE custtype = 'B'
ORDER BY discount DESCENDING.
方式5:在SELECT中使用聚合函數完成運算
在SELECT中,使用例如COUNT,SUM,MAX等函數完成數據的統計工作,直接返回運算結果。
DATA: lv_seatsocc TYPE sflight-seatsocc,
lv_sum TYPE i VALUE 0.
* -- Bad --*
SELECT seatsocc
FROM sflight INTO lv_seatsocc
WHERE carrid = 'LH'
AND fldate LIKE '2018%'.
lv_sum = lv_sum + lv_seatsocc.
ENDSELECT.
* -- Good --*
SELECT SUM( seatsocc )
FROM sflight
INTO lv_sum
WHERE carrid = 'LH'
AND fldate LIKE '2018%'.
方式6:使用UPDATE …SET更新數據庫
如果只需要更新DB中某一條數據中的特定幾個字段,使用UPDATE … SET無疑是最佳的方式。
DATA: ls_sflight TYPE sflight.
SELECT * FROM sflight
INTO ls_sflight UP TO 1 ROWS
WHERE carrid = 'LH'.
ENDSELECT.
* option 1 -
ls_sflight-price = ls_sflight-price + 100.
UPDATE sflight FROM ls_sflight.
* option 2 -
ls_sflight-price = ls_sflight-price + 100.
UPDATE sflight SET price = ls_sflight-price
WHERE carrid = ls_sflight-carrid
AND connid = ls_sflight-connid
AND fldate = ls_sflight-fldate.