概要: 私が見た MDX 結合の例のほとんどは、それぞれ数十または数百の項目を持つ、比較的小さなセットの結合を伴います。しかし、それぞれ数千または数万のアイテムを持つセットを結合する (特に「空でない結合」) ことも試してみたいと思っていますが、今のところうまく機能していません。これを機能させることができるかどうか、または Mondrian/OLAP 以外のものを使用することを検討する必要があるかどうか疑問に思っています。
具体的には、会社 (n=7000) とクライアント (n=27000) の間の相互作用を記録するキューブがあります。現在、会社とクライアントはどちらも完全にフラットな階層です。すべてのレベルと個々の会社のレベルがあり、その間に他のレベルはありません。中央のファクト テーブルと、会社用とクライアント用の個別のディメンション テーブルがあります。
私のユーザーは少なくとも、会社とクライアントの間のすべての空ではない対話を集約して、これらの行に沿って要約レポートを取得したいと考えているようです。
select
[Measures].[Amount] on columns,
NonEmptyCrossJoin([Firm].Children,
[Client].Children) on rows
from MyCube
しかし、このクエリとそのバリエーションは、テスト用の Mondrian セットアップでは機能しません。(2 GB の Java ヒープで) OutOfMemoryException が発生するか、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 はこの最適化を試みていないようです。代わりに、内部で結合を行っているように見え、最終的には特に遅くなります。mondrian.properties で mondrian.native.crossjoin.enable=true を設定しましたが、これは Mondrian が「ネイティブにする」ことができる結合タイプの 1 つではないようです。( mondrian.native.unsupported.alert=ERROR をオンにすると、対応する例外が発生します。)
ユーザーがそのような大きな次元/セットで結合を試行するのを防ぐ必要があるのか 、それともMondrianがここで探しているツールではないのか 疑問に思っています. しかし、多分私は何か間違ったことをしているのです。