所有条目慢 SELECT

Slow SELECT FOR ALL ENTRIES

下面的 SELECT 使用内部 table GIT_KUNNR_TAB 运行,包含 2.291.000 行和唯一客户端 (kunnr),需要 16 分钟才能完成。

  select kunnr umsks umskz gjahr belnr buzei bschl shkzg dmbtr bldat
           zfbdt zbd1t zbd2t zbd3t rebzg rebzj rebzz rebzt
        into corresponding fields of table git_oi_tab
      from bsid
        for all entries in git_kunnr_tab
      where bukrs  =  p_bukrs
        and kunnr  =  git_kunnr_tab-kunnr 
        and umsks  = ' '
        and augdt  =   clear_augdt
        and budat  le  p_key 
        and blart  in  s_blart
        and xref3  in  s_xref3.

BSID 总共包含 20.000.000 条记录,对于 2.291.000 个唯一客户端,它从 BSID 获得 445.000 条记录。

大多数时候 GIT_KUNNR_TAB 中有更多的行。

有没有更快的选择?

删除 FOR ALL ENTRIES 部分

很可能 WHERE 条件的其余部分具有足够的选择性。您取回的记录比必要的多,但 快得多

由于git_kunnr_tab是唯一的,你可以把它变成一个HASHED table,并在应用服务器上用它过滤git_oi_tab

SELECT kunnr umsks umskz gjahr belnr buzei bschl shkzg dmbtr bldat
       zfbdt zbd1t zbd2t zbd3t rebzg rebzj rebzz rebzt
    INTO corresponding fields of table git_oi_tab
    FROM bsid
    WHERE bukrs = p_bukrs 
      AND umsks = ' ' 
      AND augdt = clear_augdt 
      AND budat le p_key 
      AND blart in s_blart 
      AND xref3 in s_xref3.

DATA: lt_kunnr_tab TYPE HASHED TABLE of <type of git_kunnr_tab>
          WITH UNIQE KEY kunnr.
lt_kunnr_tab = git_kunnr_tab.
LOOP AT git_oi_tab ASSIGNING FIELD-SYMBOL(<fs_oi>).
  READ TABLE lt_kunnr_tab TRANSPORTING NO FIELDS
      WITH KEY kunnr = <fs_oi>-kunnr.
    IF sy-subrc <> 0
      DELETE git_oi_tab.
    ENDIF.
  ENDIF.
ENDLOOP.
FREE lt_kunnr_tab.

不是通用解决方案

如果 FAE 驱动程序 table 包含 超过 20% 的目标 table 行,完全删除它最有利于提高速度。
如果行数较少,FAE 是更好的解决方案。

但是要小心,删除 FAE 会 显着 增加生成的内部 table!

的内存消耗

对于所有条目与范围 table

网上很多地方都说Range tables比FAE快。在某些非常具体的情况下确实如此:

  • FAE 驱动程序只使用了一个字段table1
  • 驱动中的行数table比FAE一批下发的多
  • 默认批处理大小在 Oracle 中为 5,在 DB2 中为 50,在 HANA 中为 100
  • Range thable 中没有太多行导致转储
  • 最大长度为 1 048 576 字节(注释 1002491)

Range tables 可以比 FAE 更快,因为它在一个查询中发送了所有过滤条件。这当然很危险,因为查询的大小是有限的。如果它超过了设定的限制,你会得到一个转储。

但是,使用 提示 MAX_IN_BLOCKING_FACTORMAX_BLOCKING_FACTOR 您可以为 FAE 提供范围 table 的所有好处,而没有其缺点通过增加批量大小。

所以仅使用 Range tables 与实际范围 ,如 between A and C,或 not between G and J.


  1. 这不是关于速度,而是功能的正确性。 Range tables 独立处理字段,而 FAE 处理 rows

通常只有一个字段使用范围要快得多。 因此,如果您通过内部 table 中的某个键选择数据,仅比较 table 中的一个字段,将其转换为范围而不是 FAE:

TYPES:
  tr_kunnr TYPE RANGE OF kunnr.

* or just do loop/append if you on the old system (>7.4)
DATA(lr_kunnr) = VALUE tr_kunnr(
  FOR <fs_oi> IN git_oi_tab
  (
    sign    = 'I'
    option  = 'EQ'
    low     = fs_oi-kunnr
  )
). 

 select kunnr umsks umskz gjahr belnr buzei bschl shkzg dmbtr bldat
           zfbdt zbd1t zbd2t zbd3t rebzg rebzj rebzz rebzt
        into corresponding fields of table @git_oi_tab
      from bsid
      where bukrs  =  @p_bukrs
        and kunnr  in @lr_kunnr...

没找到文章,但是查了一下,单场比对的范围比FAE快很多