我拥有 Microsoft SQL Server 背景,经常使用
CROSS APPLY
和 CTE
(公用表表达式)等功能来编写查询。我目前正在尝试使用 CROSS APPLY
在 SAP HANA 中编写查询,但它似乎不受支持。
我确实发现
LEFT OUTER JOIN LATERAL
可能与 Microsoft SQL Server CROSS APPLY
等效(或 SQL 标准),但它在我正在使用的 SAP HANA 版本中不可用(SAP HANA 版本 2.00.037.02.1562323855) [系统->状态])。看来这已经在版本HANA 2.0 SPS04中发布了,但这不是我公司使用的。
这是我过去成功使用的
CROSS APPLY
替代方案的示例。但性能似乎变得很差,并且出现内存不足错误。我怀疑数据集正在增长并且变得相当大,并且查询变得效率低下。
FROM SAPECC.AUFK AS AUFK
LEFT OUTER JOIN
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY MANDT, OBJNR ORDER BY UDATE DESC) AS RowNumber
FROM SAPECC.JCDS
WHERE STAT = 'I0045' AND INACT = ''
) JCDS ON JCDS.OBJNR = AUFK.OBJNR AND JCDS.MANDT = AUFK.MANDT AND JCDS.RowNumber = 1
有什么替代方案的建议吗?
您可能想尝试相关子查询而不是
ROW_NUMBER()
:
select ...
from sapecc.aufk as a
left join sapecc.jcds as j
on j.objnr = a.objnr
and j.mandt = a.mandt
and j.stat = 'I0045'
and j.inact = ''
and j.udate = (
select max(j1.udate)
from sapecc.jcds as j1
where
j1.objnr = a.objnr
and j1.mandt = a.mandt
and j1.stat = 'I0045'
and j1.inact = ''
)
此查询应利用
(objnr, mandt, stat, inact, udate desc)
上的索引。
您可以使用与 MSSQL 和 HANA 中使用的相同的 CTE 方法:
WITH most_recent_JCDS as (
SELECT * FROM (
SELECT *
, ROW_NUMBER()
OVER (PARTITION BY MANDT, OBJNR
ORDER BY UDATE DESC) AS RowNumber
FROM SAPECC.JCDS
WHERE STAT = 'I0045'
AND INACT = '')
WHERE
RowNumber = 1)
SELECT
AUFK. ...
, JCDS. ...
FROM
SAPECC.AUFK AUFK
LEFT OUTER JOIN most_recent_JCDS JCDS
ON
(JCDS.OBJNR, JCDS.MANDT)
= (AUFK.OBJNR, AUFK.MANDT);
对性能或查询效率的担忧只能通过检查实际执行来解决。 PlanViz 和 EXPLAIN PLAN 就是用于此目的的工具。
假设某些索引“应该”有助于提供 50/50 的正确率(最多)。
LATERAL
,所以这样写:
...
FROM SAPECC.AUFK AS AUFK
LEFT OUTER JOIN LATERAL
(
SELECT *
FROM SAPECC.JCDS
WHERE STAT = 'I0045' AND INACT = ''
AND JCDS.OBJNR = AUFK.OBJNR
AND JCDS.MANDT = AUFK.MANDT
LIMIT 1
)