Являются ли Mondrian/OLAP неподходящим инструментом для объединения больших измерений/наборов?

Резюме: Большинство примеров соединений MDX, которые я видел, включали объединение относительно небольших наборов, скажем, с десятками или сотнями элементов в каждом. Но я также обнаружил, что хочу попробовать объединить (в частности, «непустое объединение») наборы, каждый из которых состоит из тысяч или десятков тысяч элементов, и пока это не работает. Мне интересно, можно ли это заставить работать, или мне, возможно, нужно рассмотреть возможность использования чего-то другого, кроме Mondrian/OLAP.

Чтобы быть конкретным, у меня есть куб, который записывает взаимодействия между Фирмами (n = 7000) и Клиентами (n = 27000). В настоящее время и Фирма, и Клиент представляют собой совершенно плоские иерархии; есть уровень «Все» и уровень «индивидуальная компания», без каких-либо промежуточных уровней. Существует центральная таблица фактов и отдельные таблицы измерений для фирм и для клиентов.

По крайней мере, мои пользователи, похоже, хотят получать сводные отчеты по этим направлениям, объединяющие все непустые взаимодействия между Фирмами и Клиентами:

select
  [Measures].[Amount] on columns,
  NonEmptyCrossJoin([Firm].Children,
                      [Client].Children) on rows
from MyCube

Но этот запрос и его варианты не работают в моей тестовой установке Мондриана. Либо я получаю исключение 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, я получу соответствующее исключение.)

Я задаюсь вопросом, нужно ли мне предотвращать попытки моих пользователей объединяться в такие большие измерения / наборы, или Mondrian, возможно, не тот инструмент, который я ищу здесь. Но может я просто что-то не так делаю.


person Chris    schedule 19.11.2011    source источник


Ответы (4)


Чтобы продолжить, я попытался настроить аналогичный куб в Sql Server Analysis Services (Sql Server 2008), и кажется, что icCube имеет точку зрения о том, что разные инструменты OLAP работают по-разному:

Еще до того, как я много узнал о передовом опыте SSAS, производительность этого типа многомерных выражений была значительно улучшена. Запрос в этих строках

select
  [Measures].[Amount] on columns,
  NON EMPTY
  crossjoin([Firms].[Firm Name].Children,
            [Clients].[Client Name].Children)
  on rows
from MyCube

превратился из нежизнеспособного с Мондрианом в примерно десять секунд под Sql Server. Возможно, это связано с тем, что MS Business Intelligence Development Studio помогает мне создать куб MOLAP по умолчанию, или, возможно, у SSAS есть более умный планировщик запросов.

В любом случае, возможно, это достаточно быстро для меня. Если нет, то я пока не уверен, насколько более оптимизированными могут быть SSAS в этом случае. (Разочаровывает то, что даже когда я повторно запускаю запрос во второй раз, это все равно занимает около 10 секунд; я надеялся, что кэширование может иметь более значительный эффект.)

Кстати, вы можете заметить, что в только что процитированном многомерном выражении я заменил исходный NonEmptyCrossJoin обычным перекрестным соединением в сочетании с NON EMPTY. Это связано с тем, что, по крайней мере, в мире Sql Server NonEmptyCrossJoin, по-видимому, считается устаревшей плохой практикой. (Это отмечено в Справочнике по языку многомерных выражений Microsoft. Моша, один из бывшие разработчики SSAS, описывает ситуацию в статье под названием MDX: NonEmpty, Exists и злобный NonEmptyCrossJoin. Краткая версия заключается в том, что NonEmptyCrossJoin имеет запутанную семантику и ограниченное применение, а начиная с Sql Server 2005 или около того, оптимизатор запросов был достаточно умен, чтобы сделать ваш запрос быстро без NonEmptyCrossJoin.) Поэтому я заменил более современный утвержденный эквивалент в приведенном выше многомерном выражении. (Он по-прежнему работает и с NonEmptyCrossJoin, хотя NonEmptyCrossJoin совсем не ускоряет процесс.)

person Chris    schedule 30.11.2011

Я не уверен на 100%, но вы пробовали установить:

mondrian.native.nonempty.enable = истина

Эта оптимизация, кажется, переводит некоторые операции на уровень sql - похоже, это может помочь.

person Codek    schedule 02.04.2012
comment
mondrian.native.nonempty.enable действительно стоит проверить в дополнение к mondrian.native.crossjoin.enable, хотя документы утверждают, что оба уже по умолчанию имеют значение true. К сожалению, у меня нет готовой установки mondrian, чтобы увидеть, пробовал ли я уже ваше предложение, или посмотреть, будет ли это иметь значение в моем случае. - person Chris; 02.04.2012
comment
Хорошо стоило упомянуть. У меня есть сборка сервера Pentaho 3.8, и для нее установлено значение false, интересно, почему! Как ни странно, мне тоже не помогло. - person Codek; 03.04.2012
comment
Всем, кто сталкивался с этим, я также рекомендую просмотреть настройки procRowCount и highCardinality. - person Codek; 11.07.2012
comment
mondrian.native.nonempty.enable=true помог мне. Я использовал непустые годы и кварталы (около 50) в качестве столбцов и непустых пользователей (около 75 000) в качестве строк, потребовалась целая вечность, прежде чем установить для этого параметра значение true, теперь меньше секунды. - person kolen; 13.03.2013
comment
да не понимаю, почему это не по умолчанию! - person Codek; 15.03.2013

Я отвечу на часть OLAP. Существует три больших семейства инструментов OLAP. РОЛАП, МОЛАП и ХОЛАП.

ROLAP, реляционный, построен на реляционной базе данных. Запрос MDX, если кеш отсутствует, выполняется в реляционной базе данных с использованием инструкции SQL. У них есть преимущество масштабируемости за счет делегирования, но их производительность зависит от базовой базы данных. QoS может быть сложным, так как это QoS db.

MOLAP, InMemory, копирование данных во внутренние структуры (память). Здесь QoS и время ответа более стабильны и быстрее, поскольку вся обработка выполняется на одном сервере. Проблема с MOLAP заключается в масштабируемости, поскольку у вас может не хватить памяти (> 100 миллионов).

HOLAP — это смесь ROLAP и MOLAP. У меня нет прямого опыта, но теоретически они могут принести лучшее из обоих миров.

Глядя на цифры, у вас не должно возникнуть проблем с инструментами MOLAP, это действительно маленький куб.

Итак, прежде чем покинуть мир OLAP, дайте шанс серверам MOLAP. Список серверов OLAP можно найти в википедии.

person ic3    schedule 20.11.2011

Mondrian OLAP не поддерживает большие базы данных.

Что ж, я разрабатываю инструмент OLAP Bitmap Join Index (BJIn OLAP), который представляет собой инструмент OLAP, основанный на Java с открытым исходным кодом. Это использует синтаксис отклонения SQL, а не MDX.

Документация здесь

Пробная версия здесь

person Anderson Carniel    schedule 13.12.2011
comment
Сэр, не могли бы вы предоставить нам вместо ссылки на пробную версию ссылку на исходный код этого открытого исходного кода программного обеспечения? На странице проекта не нашел. Спасибо. - person bpgergo; 30.01.2012