加载整个数据库表然后在内存中进行过滤,还是仅加载已过滤的条目?

时间:2019-03-03 11:22:35

标签: database sap abap opensql

我需要对数据库中的客户搜索进行编程。

我知道数据库用于管理大量数据。但是我的“导师”告诉我尽可能少地与数据库交互。

最好将整个数据库表读入内部表,然后根据用户输入的参数进行过滤:

SELECT * FROM customer INTO TABLE it_customer.

LOOP AT it_customer INTO wa.
      WHERE .... IN ...
  APPEND wa TO output.
ENDLOOP.

还是直接访问数据库表?

SELECT * FROM customer 
      INTO wa
      WHERE ... in ...
  APPEND wa TO output.
ENDSELECT.

4 个答案:

答案 0 :(得分:1)

的确,数据库访问被认为是一项昂贵的操作。 习惯以正确的方式访问可以完全提高系统的性能。

通常,减少数据库访问数量是一个很好的起点。但是,并不是唯一考虑采用“ 正确方式”方程式的人。

让我们来看看您的情况:

* A single DB access:
SELECT * 
  FROM customer
  INTO CORRESPONDING FIELDS OF TABLE @lt_customer. 

* Then some manipualtion.
* ...

陷阱:

    如前所述,从数据库到应用程序服务器的数据流非常昂贵。不仅访问量是一个因素,而且数据传输也是一个因素。如果不需要所有客户(例如客户的个人信息屏幕),那么将所有其他不需要的客户转移到应用程序服务器上将产生很大的开销。
  1. 如果整个过程只有一次(例如在过程开始时),则选择整个表可能没问题。但是,在许多流程中,数据库是在流程的中间进行更改的(例如,如果这是所有客户的概览屏幕)。在这种情况下,您将不得不刷新数据,然后再使用另一个select *进行操作。
  2. 数据库访问确实是昂贵的,但是内部操纵也不是免费的。当select *是客户数据库表中的记录数时,执行N将在lt_customer中引出N行。有时不可避免要按n^2顺序进行计算,甚至更多。随着N的增长,处理它的时间也随之增加。

我现在没时间了。当我有更多时间时,我将尝试扩大规模。祝你好运。

P.S。 SELECT... ENDSELECT.被认为是不良做法。您可以在示例here中阅读它。

答案 1 :(得分:1)

SAP在其performance notes中声明的主要原则是:

将匹配次数保持在较低水平

这意味着WHERE条件永远都不能为空,就像您打算做的那样。您永远不应该阅读整个数据库。

保持低读取次数原则仅排在第三位,也就是说,在海量数据上它的重要性降低。但也不要滥用它,也不要像第二个变体那样在循环中使用数据库操作,除非您在做一些有特殊要求的特殊事情。

要说的更多,您的代码违反了保持数据量低的原则,因为您正在获取所有列而不是所需的列。除非您确实使用了所有列,否则请避免在SELECT中使用*。

因此答案是:使用第一段代码(但是在SELECT中使用WHERE!),这样会更高效。在大多数情况下,ABAP操作要比DB操作便宜。

有关此主题的有用博客:

https://blogs.sap.com/2014/05/21/a-complete-guide-to-opensql-statements-step-by-step-tutorial-with-screenshots/

答案 2 :(得分:1)

SELECT the, fields, you, really, need
  FROM customer
  INTO TABLE @DATA(customers)
  WHERE some_attribute = @some_value
    OR some_id IN @some_range.

如果记录数量巨大,则可能要处理数据包中的数据:

SELECT the, fields, you, really, need
  FROM customer
  INTO TABLE @DATA(customers)
  WHERE some_attribute = @some_value
    OR some_id IN @some_range
  PACKAGE SIZE 1024.

  " some processing

ENDSELECT
  • 一步一步读取尽可能多的记录,以使昂贵的数据库往返次数最少。
  • 仅选择真正需要的列,并使用WHERE来最大程度地减少内存占用量和需要传输的数据量。

答案 3 :(得分:0)

使用SELECT ... INTO TABLE

当您获得更好的导师 1 时,将代码重构为合理的内容会容易得多。

,如果it_customer导致内存转储,则应使用SELECT ... ENDSELECT。


1)或DBA或CTO,负责当前非常不良政策的人