3

我有以下非常缓慢且效率低下的语句,我想选择 e071 中的所有条目,其中 obj_name 字段包含 tadir 中的 obj_name 字段的值,后跟通配符。

LOOP AT tadir ASSIGNING <fs_tadir>.

   CONCATENATE <fs_tadir>-obj_name '%' INTO gv_obj_name.

    SELECT * FROM e071 APPENDING TABLE gt_e071 
       WHERE obj_name LIKE gv_obj_name.

ENDLOOP.

有什么方法可以提高效率,因为您不能将 LIKE 语句与“For all entries in”或连接一起使用?

4

2 回答 2

2

LIKE 对于数据库来说是非常可怕的,因为你在一个循环中有这个,你很可能在每次循环迭代中扫描整个 E071。您应该尝试交换它并选择 E071 中的所有内容,然后在 SELECT...ENDSELECT 中检查您的表。我知道这听起来有悖常理,但它在我们构建的自定义 REGUH 索引上拯救了我。

SELECT * FROM e071 APPENDING TABLE gt_e071 
   WHERE obj_name LIKE gv_obj_name.

  READ TABLE tadir WITH KEY.... ASSIGNING <fs_tadir>.

ENDSELECT.

作为替代选择,而不是使用单个 like 构建一系列值并将它们批量发送到选择。它仍然会表现不佳,但会更好。

data lt_obj_range type range of e071-obj_name.
data ls_obj_range like line of lt_obj_range.

LOOP AT tadir ASSIGNING <fs_tadir>.
   ls_obj_range-sign = 'I'.
   ls_obj_range-option = 'CP'.
   CONCATENATE <fs_tadir>-obj_name '*' INTO ls_obj_range-low.
   append ls_obj_range to lt_obj_range.

endloop.

SELECT * FROM e071 APPENDING TABLE gt_e071 
       WHERE obj_name it lt_obj_range.

请注意,数据库对 select 语句的大小有限制,因此如果您的范围内有太多项目,您将得到一个简短的转储,因此将其分解为大约 200-300 行的范围。

于 2013-11-02T03:18:54.837 回答
1

使用 SQL 跟踪(事务ST05)来分析您的查询。一个主要问题——除了你可能在数据库中抛出数千个查询之外——是你根本没有使用任何索引,甚至没有执行范围扫描。这可能会迫使 DBMS 执行数千次全表扫描。如果您提供PGMIDand OBJECT,它应该会大大加快速度。

通过使用前缀来限制您正在查看的传输请求的数量可能也是一个好主意。我刚刚检查了我们的几个系统 - 根据系统的年龄,其中一半的条目E071根本不属于传输。在一个系统中,仅在本地创建了超过 450 万个条目中的 75,000 个条目,其他的是支持包等的片断列表。

从较早的问题中,我对您要实现的目标有所了解。请注意,您不能依赖主要对象名称位于部分对象名称的开头。您可能需要检查功能模块的编码,TR_CHECK_TYPE以了解部分 ( LIMU) 条目如何映射到整个对象条目 ( R3TR)。但是,我不知道有什么功能模块可以反方向工作。

我不会担心选择单个字段而不是SELECT *在这个阶段。与您在其他回复或评论中可能读到的相反,这E071是一个相对狭窄的表格,其中的字段很少,您已经需要查询中的最大字段。仅选择单个字段可能没有什么好处。

于 2013-11-01T07:36:33.700 回答