db2 - 为什么`FOR ALL ENTRIES` 会降低 DB6 上 CDS 视图的性能?
问题描述
我正在使用WHERE
其主(也是唯一的)键列上的子句从 SAP 核心数据服务(CDS 视图、SAP R/3、ABAP 7.50)读取数据。使用时性能会大幅下降FOR ALL ENTRIES
(大约 5 倍):
在我的例子中,使用普通WHERE
子句读取数据大约需要 10 秒:
SELECT DISTINCT *
FROM ZMY_CDS_VIEW
WHERE prim_key_col eq 'mykey'
INTO TABLE @DATA(lt_table1).
FOR ALL ENTRIES
在我的情况下,使用相同的方法读取数据WHERE
大约需要 50 秒:
"" boilerplate code that creates a table with one entry holding the same key value as above
TYPES: BEGIN OF t_kv,
key_value like ZMY_CDS_VIEW-prim_key_col,
END OF t_kv.
DATA lt_key_values TYPE TABLE OF t_kv.
DATA ls_key_value TYPE t_kv.
ls_key_value-key_value = 'mykey'.
APPEND ls_key_value TO lt_key_values.
SELECT *
FROM ZMY_CDS_VIEW
FOR ALL ENTRIES IN @lt_key_values
WHERE prim_key_col eq @lt_key_values-key_value
INTO TABLE @DATA(lt_table2).
我不明白为什么使用FOR ALL ENTRIES
. 由于该表lt_key_values
只有 1 个条目,我希望数据库(sy-dbsys
在我的情况下是“DB6”)执行完全相同的操作,加上一些可忽略的小开销 ≪ 40 秒。
从底层 SQL 视图而不是 CDS(及其访问控制等)中进行选择完全没有区别,添加或删除DISTINCT
关键字也没有(因为FOR ALL ENTRIES
蕴含DISTINCT
)。
解决方案
一位同事猜测,这FOR ALL ENTRIES
实际上是选择 CDS 的全部内容,并lt_key_values
在运行时将其与内部表进行比较。这似乎是对的。
使用事务st05
我记录了一个 SQL 跟踪,在这种FOR ALL ENTRIES
情况下如下所示:
SELECT
DISTINCT "ZMY_UNDERLYING_SQL_VIEW".*
FROM
"ZMY_UNDERLYING_SQL_VIEW",
TABLE( SAPTOOLS.MEMORY_TABLE( CAST( ? AS BLOB( 2G )) ) CARDINALITY 1 ) AS "t_00" ( "C_0" VARCHAR(30) )
WHERE
"ZMY_UNDERLYING_SQL_VIEW"."MANDT" = ?
AND "ZMY_UNDERLYING_SQL_VIEW"."PRIM_KEY_COL" = "t_00"."C_0"
[...]
Variables
A0(IT,13) = ITAB[1x1(20)]
A1(CH,10) = 'mykey'
A2(CH,3) = '100'
所以实际发生的是:ABAP 选择整个 CDS 内容并将内部表中的值放入类似于附加列的东西中。然后它只保留那些内部表和 SQL 结果条目匹配的值。==> 数据库级别没有优化 => 性能不佳。
推荐阅读
- java - 从嵌套列表创建地图
- java - 优化嵌套 if 语句中的嵌套 for 循环
- mysql - SQLSTATE [42000]:语法错误或访问冲突:1064。找不到语法错误
- javascript - 更改“文件夹导入”的子文件后热重载崩溃
- html - 当处于引导模式(谷歌浏览器)时,输入字段在表单字段之外
- r - 使用 geom_histogram 在 scale_x_continuous 中设置限制
- c++ - CMake 错误:链接器命令失败,退出代码为 1 和 cpp.o 文件
- gitlab - git@gitlab.com:权限被拒绝(公钥)。致命:无法从远程存储库中读取
- react-native - React-Native 文档中缺少边框?
- javascript - knex.where容易受到sql注入攻击吗?