
在 SAP S/4HANA 的 CDS 数据模型里,有一类代码看起来几乎没有任何危险气息。一个CASE表达式,一次普通的 association,再从 association 里取出一个计算字段,单独看每一层都很自然。可是一旦这些元素组合成LEFT OUTER JOIN,SQL 执行计划可能突然变得很重,内存消耗升高,CPU 时间增加,甚至出现规模巨大的 intermediate result。SAP 已经把这种模式明确归入 CDS performance anti-pattern,它的名字就是Not-Null-Preserving Left Outer Join。SAP HANA 的性能文档也进一步说明,如果 outer join 下方存在常量或者计算列,而且该计算不能保证输入为NULL时结果仍然为NULL,HANA 可能不得不先物化计算结果,再执行 outer join。真正麻烦的地方并不在CASE本身,也不在LEFT OUTER JOIN本身,而在两者之间形成了一种很强的语义约束。SQL Optimizer 原本很擅长调整执行顺序,但遇到这种结构时,它的一部分重排自由度会被锁死。这正是很多 CDS 查询看上去很简单,最终 SQL 也没有特别夸张,却仍然出现性能问题的原因之一。从一个很普通的 CDS 计算字段开始先看数据模型中的第一层Entity_1。