Резюме: Большинство примеров, которые я видел, объединений MDX включали объединение относительно небольших наборов, скажем, с десятками или сотнями элементов в каждом. Но я также хочу попробовать объединить (в частности, «непустое объединение») наборы, каждый из которых содержит тысячи или десятки тысяч элементов, и это пока не работает должным образом. Мне интересно, можно ли это заставить работать, или мне, возможно, нужно подумать об использовании чего-то другого, кроме Mondrian / OLAP.
Если говорить конкретно, у меня есть куб, который записывает взаимодействия между фирмами (n = 7000) и клиентами (n = 27000). В настоящее время и фирма, и клиент являются абсолютно плоскими иерархиями; есть уровень All и уровень отдельных компаний, между которыми нет других уровней. Существует центральная таблица фактов и отдельные таблицы измерений для фирм и клиентов.
По крайней мере, мои пользователи хотят получать сводные отчеты по этим направлениям, объединяя все непустые взаимодействия между фирмами и клиентами:
select
[Measures].[Amount] on columns,
NonEmptyCrossJoin([Firm].Children,
[Client].Children) on rows
from MyCube
Но этот запрос и его варианты не работают в моей тестовой установке Mondrian. Либо я получаю исключение OutOfMemoryException (в куче Java объемом 2 ГБ), либо 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.native.crossjoin.enable = true в моих mondrian.properties, но это не похоже на один из типов соединения, который Mondrian способен «сделать нативным». (Если я включу mondrian.native.unsupported.alert = ERROR, я получу соответствующее исключение.)
Мне остается задуматься, нужно ли мне запретить пользователям пытаться объединяться с такими большими размерами / наборами или Мондриан, возможно, не тот инструмент, который я ищу здесь. Но, может быть, я просто делаю что-то не так.