ABAP选择性能

ily*_* n. 4 database sap abap

是否存在与大查询性能相关的一般ABAP特定提示SELECT

特别是,有可能一劳永逸地关闭FOR ALL ENTRIES INvs 的问题JOIN吗?

vwe*_*ert 13

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

避免SELECT*在不需要的地方,尝试仅选择所需的字段.原因:在此过程中可能会多次映射每个值(数据库磁盘 - >数据库内存 - >网络 - >数据库驱动程序 - > ABAP内部).如果您不需要字段,则可以轻松保存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'加入'数据库表和内部(内存)表,而JOIN仅对数据库表进行操作.由于数据库对内部ABAP内存一无所知,FOR ALL ENTRIES IN语句将转换为一组WHERE语句 - 只需尝试使用ST05跟踪它.其次,使用FOR ALL ENTRIES IN时,无法从第二个表中添加值.第三,要注意FOR FOR ENTRIES IN总是意味着DISTINCT.还有一些其他陷阱 - 请务必参考在线ABAP参考,它们都列在那里.

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

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

  • 它并不聪明,只是更具可扩展性.如果需要,您可以轻松插入更多应用程序服务器(进程甚至硬件),但如果您的数据库系统遇到性能问题,则可能难以升级它... (5认同)

Noa*_*oah 5

另一个注意事项:"避免SELECT*"语句通常是正确的,但我可以告诉你它在哪里是错误的.
无论如何你要占用大部分字段,并且你有几个查询(在同一个程序中,或者可能在同一时间运行的不同程序)占用大部分字段,特别是如果它们不同缺少的字段.

这是因为App Server数据缓冲区基于选择查询签名.如果确保使用相同的查询,则可以确保可以使用缓冲区而不是再次访问数据库.在这种情况下,SELECT*优于选择90%的字段,因为您更有可能使用缓冲区.

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


小智 3

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