总结:我见过的大多数 MDX 连接示例都涉及连接相对较小的集合,例如每个集合包含数十或数百个项目。但我发现自己也想尝试加入(特别是“非空加入”)集合,每个集合都有数千或数万个项目,但到目前为止效果不佳。我想知道这是否可以工作,或者我是否需要考虑使用 Mondrian/OLAP 以外的东西。
具体来说,我有一个记录公司 (n=7000) 和客户 (n=27000) 之间交互的多维数据集。目前,公司和客户都是完全扁平的层次结构;有所有级别和个人公司级别,中间没有其他级别。有一个中心事实表,以及针对公司和客户的单独维度表。
我的用户至少似乎希望获得这些方面的摘要报告,汇总公司和客户之间的所有非空交互:
select
[Measures].[Amount] on columns,
NonEmptyCrossJoin([Firm].Children,
[Client].Children) on rows
from MyCube
但是这个查询及其变体在我的测试蒙德里安设置中不起作用。要么我得到一个 OutOfMemoryException(在 2GB Java 堆上),要么 Java 似乎在 mondrian.rolap.RolapResult$AxisMember.mergeTuple(TupleCursor) 中花费了不可思议的时间。(如果有帮助,我可以提供更完整的堆栈跟踪。)“不可能的长”是指 Java 在我放弃之前会在查询中苦苦挣扎几个小时。
我最初预计上述查询可以正常执行,因为从概念上讲,只需按照以下几行执行 SQL 查询就可以有效地完成:
select Firm, Client, Sum(Amount) as n
from fact, firm, client
where fact.firmid = firm.firmid and fact.clientid = client.clientid
group by Firm, Client
(实际上,如果我直接在 MySql 中执行这样的操作,执行时间不会超过 15 秒。)
但从调试日志来看,蒙德里安似乎并没有尝试这种优化。相反,它似乎是在内部进行连接,并且最终速度特别慢。我在我的 mondrian.properties 中设置了 mondrian.native.crossjoin.enable=true,但这似乎不是 Mondrian 能够“使本地化”的连接类型之一。(如果我打开 mondrian.native.unsupported.alert=ERROR 那么我会得到相应的异常。)
我想知道是否需要阻止我的用户尝试加入如此大的维度/集合,或者 Mondrian 是否可能不是我在这里寻找的工具。但也许我只是做错了什么。