我有以下,非常缓慢且效率低下的语句,我想在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'或join?
答案 0 :(得分: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.
作为替代选择,而不是选择使用单个类似构建一系列值并将其发送到批量选择。它仍然表现不错但更好。
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行的范围。
答案 1 :(得分:1)
使用SQL跟踪(事务ST05
)来分析您的查询。其中一个主要问题 - 除了您可能在数据库中丢弃数千个查询之外 - 将是您根本不使用任何索引,甚至不执行范围扫描。这可能会迫使DBMS执行数千次全表扫描。如果您要提供PGMID
和OBJECT
,那么它应该会非常显着地加快速度。
通过使用其前缀来限制您正在查看的传输请求数也可能是个好主意。我刚检查了几个系统 - 根据系统的使用年限,E071
中的一半条目根本不属于传输系统。在一个系统中,本地只创建了超过450万个条目的75,000个条目,其他条目是支持包的片段列表等。
From an earlier question,我已经知道你想要实现的目标。请注意,您不能依赖主要对象名称位于部分对象名称的最开头。您可能需要检查功能模块TR_CHECK_TYPE
的编码,以了解部分(LIMU
)条目如何映射到整个对象条目(R3TR
)。但是,我不知道一个功能模块会反向运行。
我不担心在这个阶段选择单个字段而不是SELECT *
。与您在其他回复或评论中可能阅读的内容相反,E071
是一个相对较窄的表,字段很少,您已经需要查询中的最大字段。仅选择单个字段可能获得的收益很少。