从手工 join 到数据库原生计算模型,理解 SAP HANA 中 window function 与 CDS hierarchy 为什么往往更高效
在 SAP HANA 项目里,经常会看到一种很有代表性的性能问题。业务需求其实只是想解决「每组取最新一条」「每个销售订单找金额最大的三个行项目」「比较当前记录和上一条记录」「从某个组织节点向下找到全部子节点」之类的问题,可 SQL 或 CDS 最终却被写成了好几层self join,甚至出现一张大表反复和自己连接的情况。数据量小时,这种写法通常也能跑。到了几千万甚至上亿行之后,SQL 执行计划里很容易开始出现大规模join、中间结果集膨胀、重复扫描、重复排序、巨大的临时结果等现象。所以「善用window function还有CDS hierarchy,遇到合适的场景,比自己用join实现效率高很多」这句话,真正想表达的并不是简单的「少写几个join」。它背后更重要的一层思想是,我们应该尽量把业务问题直接表达成数据库能够理解的计算语义,而不是自己拿最基础的关系运算去模拟数据库本来已经提供的高级算法。window function对应的是「在一组有顺序的数据中做分析」。CDS hierarchy对应的是「在具有父子关系的数据中做递归导航」。而普通join表达的是「根据连接条件把两个关系集合组合起来」。三者解决的问题并不处于同一个抽象层次。如果一个问题本来属于窗口计算,却硬写成join,或者一个问题本来属于层级遍历,却通过五六次self