" 不好:循环中单条记录访问 LOOP AT lt_keys INTO ls_key. SELECT SINGLE * FROM sflight INTO ls_flight WHERE carrid = ls_key-carrid AND connid = ls_key-connid. APPEND ls_flight TO lt_result. ENDLOOP.
" 好:数组读取 IF lt_keys IS NOT INITIAL. SELECT * FROM sflight INTO TABLE lt_result FOR ALL ENTRIES IN lt_keys WHERE carrid = lt_keys-carrid AND connid = lt_keys-connid. ENDIF.
" 最好:JOIN(如果可能) SELECT f~* INTO TABLE lt_result FROM sflight AS f INNER JOIN some_table AS s ON f~carrid = s~carrid.
方式
数据库往返
性能
循环中的 SELECT SINGLE
n(很差)
O(n) 次查询
FOR ALL ENTRIES
1(或少量)
良好
JOIN
1
最佳
FOR ALL ENTRIES 性能
考虑事项
详情
检查 IS NOT INITIAL
空表 = 全表扫描
精简驱动表
SORT + DELETE ADJACENT DUPLICATES
限制驱动表大小
大表分批处理
使用索引字段
WHERE 字段应匹配索引
嵌套 SELECT 反模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
" 反模式:嵌套 SELECT SELECT * FROM spfli INTO TABLE lt_routes. LOOP AT lt_routes INTO ls_route. SELECT * FROM sflight INTO TABLE lt_flights " 每条路线一次查询! WHERE carrid = ls_route-carrid AND connid = ls_route-connid. " 处理 ENDLOOP.
" 正确:单次 JOIN SELECT p~carrid, p~connid, p~cityfrom, f~fldate, f~price INTO TABLE lt_result FROM spfli AS p INNER JOIN sflight AS f ON p~carrid = f~carrid AND p~connid = f~connid.
⛔循环中的 SELECT 是最常见的性能杀手。始终用 JOIN、FOR ALL ENTRIES 或预缓冲替换。