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中 - 表的内容被分成多个集合,然后转换查询(见上文)并重新运行对于每一组.
另一个注意事项:"避免SELECT*"语句通常是正确的,但我可以告诉你它在哪里是错误的.
无论如何你要占用大部分字段,并且你有几个查询(在同一个程序中,或者可能在同一时间运行的不同程序)占用大部分字段,特别是如果它们不同缺少的字段.
这是因为App Server数据缓冲区基于选择查询签名.如果确保使用相同的查询,则可以确保可以使用缓冲区而不是再次访问数据库.在这种情况下,SELECT*优于选择90%的字段,因为您更有可能使用缓冲区.
另请注意,从我测试的最后一个版本开始,ABAP DB层不够智能,无法识别SELECT A,B与SELECT B,A相同,这意味着您应该始终按相同的顺序放置您所使用的字段(最好是表顺序),以便再次确保应用程序上的数据缓冲区得到充分利用.