繁体   English   中英

ABAP选择性能提示?

[英]ABAP select performance hints?

是否有与大型SELECT查询的性能相关的特定ABAP 的一般提示?

特别是,是否可以一劳永逸地关闭FOR ALL ENTRIES INJOIN

一些(或多或少)ABAP 特定的提示:

避免在不需要的地方使用 SELECT * ,尽量只选择需要的字段。 原因:每个值在这个过程中可能会被多次映射(DB Disk --> DB Memory --> Network --> DB Driver --> ABAP internal)。 如果您不需要这些字段,则很容易节省 CPU 周期。 如果您 SELECT * 一个包含像 STRING 这样的 BLOB 字段的表,请务必小心,这会完全降低您的数据库性能,因为 blob 内容通常存储在不同的页面上。

不要 SELECT ... ENDSELECT 用于中小型结果集,而使用 SELECT ... INTO TABLE 。 原因: SELECT ... INTO TABLE 执行单次提取并且不会保持游标打开,而 SELECT ... ENDSELECT 通常会为每次循环迭代提取一行。

这是一种都市神话——使用SELECT作为循环语句不会降低性能。 但是,这将在循环期间保持打开的游标,这可能会导致不需要的(但不是严格与性能相关的)影响。

对于大型结果集,请使用游标和内部表。 原因:同上,避免占用过多堆空间。

不要 ORDER BY,而是使用 SORT。 原因:应用服务器的可扩展性更好。

小心嵌套的 SELECT 语句。 虽然它们对于小的“内部结果集”非常方便,但如果嵌套查询返回一个大的结果集,它们将是一个巨大的性能猪。

衡量,衡量,再衡量如果您担心性能,请不要假设任何事情。 创建一组具有代表性的测试数据并针对不同的实现运行测试。 了解如何使用 ST05 和 SAT。

没有办法“一劳永逸”结束你的第二个问题。 首先,FOR ALL ENTRIES IN 'joins'一个数据库表和一个内部(内存)表,而JOIN 只对数据库表进行操作。 由于数据库对内部 ABAP 内存一无所知,因此 FOR ALL ENTRIES IN 语句将转换为一组 WHERE 语句 - 只需尝试使用 ST05 来跟踪它。 其次,当使用 FOR ALL ENTRIES IN 时,您不能从第二个表中添加值。 第三,请注意 FOR ALL ENTRIES IN 总是意味着 DISTINCT。 还有一些其他陷阱 - 请务必查阅在线 ABAP 参考,它们都列在那里。

如果第二个表中的记录数很少,则两个语句的性能应该大致相同——数据库优化器应该只从第二个表中预选所有值,并使用智能连接算法来过滤第一个表。 我的建议:使用任何感觉良好的东西,不要试图将代码调整为难以辨认。

如果第二个表中的记录数超过某个值,则使用 FOR ALL ENTRIES IN 会发生 Bad Things [TM] - 表的内容被拆分为多个集合,然后查询被转换(见上文)并重新运行对于每组。

另一个注意事项:“避免 SELECT *”语句通常是正确的,但我可以告诉您它在哪里错误。
当您无论如何都要使用大部分字段时,并且您有多个查询(在同一程序中,或可能同时运行的不同程序中)使用大部分字段时,尤其是当它们不同时缺少的字段。

这是因为应用服务器数据缓冲区基于选择查询签名。 如果您确保使用相同的查询,那么您可以确保可以使用缓冲区而不是再次访问数据库。 在这种情况下,SELECT * 比选择 90% 的字段更好,因为您更有可能使用缓冲区。

另请注意,在我测试的上一个版本中,ABAP DB 层不够智能,无法将 SELECT A, B 识别为与 SELECT B, A 相同,这意味着您应该始终按相同顺序放置字段(最好是表顺序)以再次确保应用程序上的数据缓冲区得到很好的使用。

我通常遵循 SAP 的这个 pdf 中所述的规则: “使用 ABAP 进行高效的数据库编程”它显示了很多优化查询的技巧。

这个问题永远不会得到完全回答。

用于访问数据库的 ABAP 语句被整个系统的不同组件(SAP 和 DB)解释多次。 每个组件的行为取决于组件本身、它的版本和设置。 解释的主要部分是在 SAP 端的 DB 适配器中完成的。

达到最高性能的唯一可行方法是在特定系统(SAP 版本和数据库供应商和版本)上进行测量。

交易 SE30 中也有相当广泛的提示和技巧。 它甚至允许您(取决于授权)编写自己的代码片段并对其进行测量。

不幸的是,我们无法结束“所有条目”与“加入”的争论,因为它非常依赖于您的环境的设置方式、您使用的数据库服务器、表索引的效率等。

简单的答案是让数据库服务器尽可能多地做。 对于“所有条目”与加入问题,这意味着加入。 除非每个有经验的 ABAP 程序员都知道它从来没有那么简单。 你必须尝试不同的场景并像 vwegert 所说的那样进行测量。 还要记住在您的实时系统中进行测量,因为有时硬件配置或数据集显着不同,在您的实时系统中得到的结果与测试结果完全不同。

我通常遵循以下约定:

  1. 永远不要select * ,只选择必填字段。
  2. 永远不要使用“进入相应的表”,而是创建具有所有必填字段的本地结构。
  3. 在 where 子句中,尽量使用尽可能多的主键。
  4. 如果选择获取单个记录并且所有主键都包含在 where 子句中,请使用Select single ,否则使用SELECT UP TO TO 1 ROWS, ENDSELECT
  5. 尝试使用 Join 语句来连接表,而不是使用FOR ALL ENTRIES
  6. 如果无法避免所有条目,请确保内部表不为空并删除重复条目以提高性能。

除了其他答案外,还有两点:

  • 通常,您将JOIN用于数据库中的两个或多个表,并使用FOR ALL ENTRIES IN将数据库表与内存中的表连接起来。 如果可以,请JOIN

  • 通常IN运算符比FOR ALL ENTRIES IN更方便。 但是内核将IN翻译成一个长的 select 语句。 这种语句的长度是有限的,当它变得太长时你会得到一个转储。 在这种情况下,尽管有性能影响,您还是被迫使用FOR ALL ENTRIES IN

使用内存数据库技术,最好可以使用 JOIN 和 SUM 等数据库聚合函数在数据库端完成所有数据和计算。

但如果你不能,至少尽量避免在循环中访问数据库。 当然,还要避免在不使用索引的情况下读取数据库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM