首页 > 解决方案 > 慢速选择所有条目

问题描述

下面的 SELECT 使用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.

有没有更快的选择?

标签: abapopensql

解决方案


删除所有条目部分

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

由于git_kunnr_tab是独一无二的,您可以将其转换为 HASHED 表,并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 驱动程序表包含超过 20%的目标表行,则完全删除它最有利于速度。
如果行数较少,FAE 是更好的解决方案。

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

FOR ALL ENTRIES vs Range 表

您可以在互联网上的许多地方看到Range 表比 FAE 更快。在一些非常特殊的情况下确实如此:

  • 仅使用 FAE 驱动程序表1​​ 中的一个字段
  • 驱动程序表中的行数多于 FAE 一批发送的行数
  • 默认情况下,批量大小在 Oracle 中为 5,在 DB2 中为 50,在 HANA 中为 100
  • Range 表中没有太多行会导致转储
  • 最大长度为 1 048 576 字节(注 1002491)

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

但是,使用该提示 MAX_IN_BLOCKING_FACTORMAX_BLOCKING_FACTOR您可以为 FAE 提供范围表的所有好处,而不会通过增加批量大小来获得它的缺点。

因此,请仅使用具有实际范围的范围表,例如between A and Cnot between G and J


  1. 这不是关于速度,而是关于功能的正确性。范围表独立处理字段,而 FAE 处理行

推荐阅读