HANA SQL 连接替代 CROSS APPLY / LATERAL

问题描述 投票:0回答:3

我拥有 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

有什么替代方案的建议吗?

sql left-join query-optimization hana
3个回答
0
投票

您可能想尝试相关子查询而不是

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)
上的索引。


0
投票

您可以使用与 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 的正确率(最多)。


0
投票

HANA 2.0 SPS04 - SQL 支持标准 SQL

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
) 
© www.soinside.com 2019 - 2024. All rights reserved.