从内部表填充范围表,没有重复项

时间:2018-08-17 09:45:04

标签: performance abap

我想知道什么通常更快:

  • 过滤掉重复项,然后执行选择
  • 直接选择重复项

我认为可能是第一个,但我不知道-
如何在我的代码中很好地和有效地集成重复项的删除?

DATA:
  lt_itab       TYPE TABLE OF string,
  lt_range_itab TYPE RANGE OF string
  .

* Populating itab with duplicates
* Can the following somehow become a neat one-liner? This is ugly!
APPEND '1'  TO lt_itab.
APPEND '2'  TO lt_itab.
APPEND '2'  TO lt_itab.
APPEND '3'  TO lt_itab.
APPEND '4'  TO lt_itab.
APPEND '4'  TO lt_itab.

*Populating range table from itab
*Should one remove the duplicates here for a performance boost in the upcoming select?
*If so - how?
*-------------------------------------------------------
lt_range_itab = VALUE #(
  FOR <ls_itab> IN lt_itab
  ( sign = 'I'
    option = 'EQ'
    low = <ls_itab> )
).

*...or is such a select usually faster than the time it takes to remove the duplicates?
*-------------------------------------------------------
*SELECT *
*  FROM       anyTable
*  INTO TABLE @DATA(lt_new_data)
*  WHERE      anyProperty NOT IN @lt_range_itab.

2 个答案:

答案 0 :(得分:2)

这么多问题...:-)

编辑:我在答案中的讨论之后修改了此答案

  

通常更快?

即使范围中存在一些重复项,优良的数据库也会快速选择。 Oracle's optimizer, for example, removes duplicates on its own。相比之下,SAP HANA的速度可能会变慢,但其基于字典的体系结构通常会将其保持在可以忽略的水平。因此,一般而言,我认为没有必要在每个查询之前删除重复项。

但是,如果优化器不是最佳选择并且有大量重复项,则事情可能会出错。因此,如果您期望重复,则最好保留安全性并在查询前将其删除。

还要注意范围表有长度限制。它们被转换为带有IN子句的SQL语句,并且SQL语句字符串具有最大字符数。因此,重复删除可能是使查询完全正常工作的必要策略。

更长的范围可以转换为FOR ALL ENTRIES,这将查询打包,并允许更长的范围。但是,该语句形式导致与数据库的多次往返,并且将确定在查询中重复。

  

以下内容可以以某种方式变成整洁的单线吗?

DATA(lt_itab) = VALUE string_table( ( `1` ) ( `2` ) ( `2` ) ( `3` ) ( `4` ) ( `4` ) ).

或者立即按照下面的Sandra的建议:

SELECT ... WHERE anyProperty NOT IN ('1','2','3','4')
  

如果是-怎么做?

SORT lt_range_tab.
DELETE ADJACENT DUPLICATES FROM lt_range_tab.

最后但并非最不重要,请注意,anyProperty IN @lt_range_tab可能比反向NOT IN变体快得多。数据库倾向于保留 positive 索引,这些索引对肯定查询的响应最佳。如果有可能,例如因为您要过滤具有固定值列表的字段,所以在将过滤器发送到数据库之前,最好将其反转。

答案 1 :(得分:2)

第一个当然更快,因为使用物理磁盘进行的数据库操作要比内存中操作慢得多。

对性能的影响是否明显是另一个问题;这取决于重复选择的数量和数据量。

一个众所周知的示例是SELECT ... FOR ALL ENTRIES构造,如果不删除重复项,可能会对性能产生重大影响,因为ABAP在内部将其转换为多个SELECT,因此相同的数据可能会被选择多次(然后在ABAP一侧将其删除)。

总之,除非您确定数据量很小,否则请确保在SELECT之前没有重复项。

相关问题