具有退化维度的蒙德里安表现不佳

时间:2014-06-13 18:03:55

标签: performance mondrian degenerate-dimension

我有一个应用程序,它收集性能指标并将它们存储在datamart中。然后我使用Mondrian来启用数据的分析和临时探索。我每天收集大约5e6行,METRIC表的总大小约为300M行。

我们"颜色"我们的数据基于与SLA的指标比较。颜色正好有5个不同的值。当我们进行简单的MDX查询以获取特定日期范围(例如1天)的数据的颜色分布时,我们会看到如下查询:

  

2014-06-11 23:17:08,042 DEBUG [sql] - 223:SqlTupleReader.readTuples   [[颜色]。[颜色]]:执行sql [select" METRIC"。" COLOR" as" c0"   来自" METRIC" "度量"按" METRIC"。" COLOR"订购   "度量"" COLOR" ASC NULLS LAST] 2014-06-11 23:17:58,747 DEBUG [sql] -   223:,exec 50704 ms

为了提高性能,datamart包括小时和日级别的聚合表,两个聚合表都包含COLOR列。

我知道Mondrian非常依赖于底层的数据库性能,但实际上没有办法调整它。我可以在COLOR上创建一个索引(因为索引的完整扫描将比表的完整扫描略快),但在300M行表上创建一个具有5个不同值的索引似乎很愚蠢。日聚合表有大约500K行,并且对这个表执行几乎相同的查询会明显更快,但Mondrian似乎总是转到这些维查询的基本事实表。

我的问题是,有没有办法避免这种查询?如果我无法避免它,是否可以让Mondrian使用聚合表进行此类查询?我在此维度/层次结构的单个级别中指定了approxRowCount,并且消除了类似的查询以获取值的计数。我还没有挖掘蒙德里安的来源,而是确定是否有可能使用聚合表,或者我的部分是否存在阻止它的配置。

编辑澄清:

我可能没有很好地提出我的问题 - 让我试着澄清一下。我的MDX查询类似于:

select [Color].[Color].Members on columns,
       {[Measures].[Metric Value], [Measures].[Count]} on rows
from [Metric]
where [Time].[2014].[June].[11]

我可以看看这个,然后手写一个回答这个查询的SQL查询

select COLOR, avg(VALUE), sum(FACT_COUNT) 
from AGG_DAY_METRIC
where YEAR = 2014 
  and MONTH = 6
  and DAY_OF_MONTH = 11
group by COLOR

数据库在大约100ms扫描大约4K行时回答此查询。蒙德里安需要几分钟才能回答 查询,因为它会执行多个不直接回答MDX查询的查询,而是获取有关该查询的信息 尺寸。在上面的例子中,数据库必须扫描300M行,花费50秒,以返回有5个可能的行 颜色。如果颜色在正常维度表中,则只有5行,但在简并维度中可以有100行 数百万行。

所以我的问题是:

a)有没有办法告诉蒙德里安退化维度的值并避免这些查询?

b)有没有办法让Mondrian从聚合表中回答这些查询?

3 个答案:

答案 0 :(得分:1)

此问题已解决,不是通过修改Mondrian架构或应用程序中的任何内容,而是修改数据库。在这种情况下,数据库是Oracle,我们能够创建一个启用了查询重写的物化视图。

物化视图是根据Mondrian发出的确切查询创建的。由于颜色值不会经常变化(在我们的情况下几乎从不),因此物化视图每天都会进行一次完全刷新。

在这种情况下,查询从花费分钟到毫秒。如果您遇到类似这样的问题并且您的数据库是Oracle,那么这是一种加速具有低基数的退化维度的元组分辨率的好方法。

答案 1 :(得分:0)

在不了解您的架构的情况下很难给出任何具体指示,但在我看来,您必须确保必须将具有特定颜色(计数)的行数标记为聚合度量({{ 1}}或Count)。

请注意,这些聚合不是连续计算的(我认为支持数据存储会很重,而且Mondrian不会在内存中保留一个流动的集合来处理传入的事实。)

可以指定聚合在特定时间(每晚,每小时......)运行/重建。这会使蒙德里安有点不适合进行实时分析,但你应该可以对历史数据进行几乎即时的查询。

答案 2 :(得分:0)

如果您的维度在300M事实表中有5个不同的值,则它不应该是简并维度。它应该在一个单独的维度表中。如果它的基数接近完整的事实表行数,则只能使用退化维度,使单独的表无意义,因为没有显着的存储节省并且加入维度会导致大量数据被读取;

如果你把颜色放在一个单独的昏暗桌子上,那么任何"阅读元组"查询将在几毫秒内返回结果,您的问题就解决了。

然而,更多的问题是,Mondrian应该能够从agg表中选择昏暗的值。除非你在多维数据集中有明确计数的聚合器,否则你处于一个棘手的情况下(除非有一个与你需要的详细程度完全匹配的聚合表,Mondrian很可能会扫描这个事实表)。

您还应将此简并维度的highCardinality属性设置为True。即使只有5个不同的值,具有highCardinality = false告诉Mondrian,扫描整个维度以填充成员列表是安全的。将其设置为true会停止此扫描。

您还应该为此列添加索引。将索引添加到事实表中的每个键和退化维度列始终是一个好主意。使用索引,DB应该比SQL查询快得多。

最后,您有一个300M行事实表。您使用的DBMS是什么?它是面向列的DB吗?如果没有,您应该尝试将它们作为数据存储的替代方案。面向列的DB与面向行的DB相比,对于类似Mondrian的查询具有显着的性能提升。有一些很好的选择,你应该试驾它们。