ABAP BINARY SEARCH |
您所在的位置:网站首页 › 二分法注意点 › ABAP BINARY SEARCH |
二分法检索(binary search)又称折半检索,其基本思想是设字典中的元素从小到大有序地存放在数组(array)中: 首先将给定值key与字典中间位置上元素的关键码(key)比较,如果相等,则检索成功; 否则, 若key小,则在字典前半部分中继续进行二分法检索; 若key大,则在字典后半部分中继续进行二分法检索。 这样,经过一次比较就缩小一半的检索区间,如此进行下去,直到检索成功或检索失败。 二分法检索是一种效率较高的检索方法,要求字典在顺序表中按关键码排序。 对于二分查找,表必须根据特殊的搜索关键字来升序排列,否则这个搜索不会找到正确的行。 例子: CLEAR: lv_gl_s,lv_gl_h. READ TABLE it_gl_result INTO lv_gl_s WITH KEY racct = -racct drcrk = 'S' BINARY SEARCH. READ TABLE it_gl_result INTO lv_gl_h WITH KEY racct = -racct drcrk = 'H' BINARY SEARCH. lv_gl_data-ba_amount = lv_gl_s-hslvt - ABS( lv_gl_h-hslvt ).
__________________________________________________________________________________________________________________________________________ 在维护公司SAP的过程中,遇到一个问题,困扰了很久! 简单描述一下问题:(为了不牵扯公司业务,这是抽取问题)将主要的三个字段 存在一个内表TAB2,如图所示: 需要强调一下,真是的内表比TAB2要多很多字段,(这是重点)
首先对系统中真实的内表进行了排序,其中主要的三个字段的排序如TAB2所示, (如果是内表TAB2,对COLUMN1排序的话,默认的COLUMN3也会自动安装升序排列): SORT TAB2 BY COLUMN1 . 得到下图:
使用二分查找: READ TABLE TAB2 WITH KEY COLUMN1 = '0800113864' COLUMN2 = '2012' COLUMN3 = '3018054318' BINARY SEARCH. 返回 SY-SUBRC = 8. 即查询没有相关数据!
这就是问题的情况所在!!
我发现问题的过程可以理解为如下步骤: 1. 首先定位到5条记录的中间那条记录,即第3条记录,然后对比COLUMN3。 2. 第3条记录的COLUMN3数据如果不等于 '3018054318' ,则从第3条至第5条记录的中间那条记录,即第4条记录,然后对比COLUMN3。 3. 第4条记录的COLUMN3数据如果不等于 '3018054318' ,则比较第5条记录然后对比COLUMN3。 4. 由于都没有等于 '3018054318' 的记录,则返回SY-SUBRC = 8。
解决此问题的关键: 在于对内表的排序,如果在 READ TABLE TAB2 WITH KEY COLUMN1 = '0800113864' COLUMN2 = '2012' COLUMN3 = '3018054318' BINARY SEARCH. 时候,使用到COLUMN1 = '0800113864' COLUMN2 = '2012' COLUMN3 = '3018054318' ,则对此系统中内表排序的时候需要依照此三个字段进行排序。 ______________________________________________________________________________________________________________________________ 1、使用where语句 不推荐 Select * from zflight. Check : zflight-airln = ‘LF’ and zflight-fligh = ‘BW222’. Endselect. 推荐 Select * from zflight where airln = ‘LF’ and fligh = ‘BW222’. Endselect. 2、使用聚合函数 不推荐 Maxnu = 0. Select * from zflight where airln = ‘LF’ and cntry = ‘IN’. Check zflight-fligh > maxnu. Maxnu = zflight-fligh. Endselect. 推荐 Select max( fligh ) from zflight into maxnu where airln = ‘LF’ and cntry = ‘IN’. 3、使用视图代替基本表查询 不推荐 Select * from zcntry where cntry like ‘IN%’. Select single * from zflight where cntry = zcntry-cntry and airln = ‘LF’. Endselect. 推荐 Select * from zcnfl where cntry like ‘IN%’ and airln = ‘LF’. Endselect. 4、使用INTO table 代替select endselect 不推荐 Refresh: int_fligh. Select * from zflight into int_fligh. Append int_fligh. Clear int_fligh. Endselect. 推荐 Refresh: int_fligh. Select * from zflight into table int_fligh. 5、使用批量修改内表代替逐行修改 不推荐 Loop at int_fligh. If int_fligh-flag is initial. Int_fligh-flag = ‘X’. Endif. Modify int_fligh. Endloop. 推荐 Int_fligh-flag = ‘X’. Modify int_fligh transporting flag where flag is initial. 6、使用二分法查询,提高查询内表数据速度 不推荐 Read table int_fligh with key airln = ‘LF’. 推荐 Read table int_fligh with key airln = ‘LF’ binary search.
SAP ABAP 性能优化技巧 — 使用二分查找(Binary Search)选项 READ命令使用顺序查找数据表,这会降低处理速度。取而代之,使用binary search的附加命令,可以使用二分查找算法,可以帮助加快内表查找速度。 在使用binary search之前必须首先将内表排序,否则有可能找不到记录,因为二分查找反复将查找区间对半划分,如果要查找的值小于查找区间的中间位置的数据项值,则查找区间将缩小到前半个区间,否则查找将局限于后半区间.
不推荐使用:
Read table int_fligh with key airln = ‘LF’.
推荐使用: SORT int_fligh by airln. Read table int_fligh with key airln = ‘LF’ binary search.
应用: with key 后面不能使用比较符 < >. read table itab with key matnr = lt_mseg_n-matnr pvprs > 0 . 这种写法不对。
可以变通的写这条语句。 LOOP at lt_ckmlcr WHERE matnr = lt_mseg_n-matnr AND pvprs > 0. ......... exit. endloop. 7、两个内表添加使用批量增加代替逐行 不推荐 Loop at int_fligh1. Append int_fligh1 to int_fligh2. Endloop. 推荐 Append lines of int_fligh1 to int_fligh2. 8、 使用FOR ALL Entries 不推荐 Loop at int_cntry. Select single * from zfligh into int_fligh where cntry = int_cntry-cntry. Append int_fligh. Endloop. 推荐 Select * from zfligh appending table int_fligh For all entries in int_cntry Where cntry = int_cntry-cntry. 9、使用sort by 代替order by 10、避免使用SELECT DISTINCT语句 使用的 ABAP SORT + DELETE ADJACENT DUPLICATES 代替. 11、两个实例 DATA: BEGIN OF it_mara OCCURS 0, matnr LIKE mara-matnr, maktx LIKE makt-maktx, END OF it_mara. 第一种写法: Select matnr INTO it_mara FROM mara. APPEND it_mara. ENDSelect. 第二种写法(high performace): Select matnr INTO TABLE it_mara FROM mara. ========================================== DATA: BEGIN OF it_mara OCCURS 0, matnr LIKE mara-matnr, maktx LIKE makt-maktx, END OF it_mara. DATA: BEGIN OF it_makt OCCURS 0, matnr LIKE mara-matnr, maktx LIKE makt-maktx, END OF it_makt. 第一种写法: LOOP AT it_mara. Select SINGLE maktx INTO it_mara-maktx FROM makt Where matnr = it_mara-matnr AND spras = sy-langu. MODIFY it_mara TRANSPORTING maktx. ENDLOOP. 第二种写法(high performace) Select matnr maktx INTO TABLE it_makt FROM makt FOR ALL ENTRIES IN it_mara Where matnr = it_mara-matnr and spras = sy-langu. ========================================= 1 数据——>工作区,工作区——>内表, 2 数据——>内表 很明显少了一个过程 效率自然高了 如果数据量越大,效果是可想而知的
|
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |