我有一个MDX引用2008 R2企业版多维数据集,该多维数据集从功能角度返回所需的数据。但是,执行此查询需要5-10分钟,对于在SSRS报告中执行此查询的最终用户来说,这是不可访问的。
查询如下:
With Member [Measures].[CurrentPaidAmount] as
Sum (
Tail(nonempty(descendants([Valuation Date].[DateHierachy].currentmember,4),[Measures].[SaleCount]),1),
[Measures].[CurrentTotalPaidAmt]
)
Member [Measures].[PreviousPeriodPaidAmount] as
Sum (
Tail(descendants([Valuation Date].[DateHierachy].currentmember.prevmember,4),1),
[Measures].[CurrentTotalPaidAmt]
)
Member [Measures].[YTDCurrentPaidAmount] as
([Measures].[CurrentPaidAmount] - [Measures].[PreviousPeriodPaidAmount])
select non empty
( {[Valuation Date].[DateHierachy].[Year]}, {[Valuation Date].[Year].children},
{[Valuation Date].[Month].[All]}, {[DimLocation].[State].[All]},
{[DimSeller].[Store].children}, {[DimProduct].[ProductCode].children},
{[DimProgram].[ProgramLine].children ) on rows,
[Measures].[YTDCurrentPaidAmount] on columns
from
[CB_Sales]这个基本事实表以累积的方式存储支付总额的度量,这意味着在一个月的最后一天,从一开始就为某一特定产品支付的总美元是计算出来的。这将意味着,在每个月底,该月份的支付总额被添加到前一个月的金额中,以便及时为所涉产品创建一个总计的支付金额。
我的要求是计算每个产品单独支付的每一年的总金额。
请考虑以下示例数据集,其中列出了特定产品到目前为止支付的美元总额:
12/2010产品A: 25.00美元
11/2011 -产品A: 50.00美元
12/2011 -产品A: 100.00美元
1/2012 -产品A: 150.00美元
2/2012 -产品A: 160.00美元
3/2012 -产品A: 200.00美元
如果我想获得仅为上述产品A的2011历年支付的全部美元,我将获得截至2010年12月的产品A支付的总日历美元(即25.00美元),并将此金额从截至12/2011的已支付美元总额(100.00美元)中减去。
减去这两个值,差额为75.00美元:
($100.00 - $25.00) = $75.00
这将表明,仅在2011历年内就为产品A总共支付了75美元。
说到这里,回到上面的MDX查询,我创建了两个计算成员来执行这个计算。
成员(1):
Measures.CurrentPaidAmount
此计算的成员根据Valuation Date.DateHierachy.Year属性的当前成员获取当前日历年度记录的最后一个非空美元支付金额。由于就目前2012历年(最后一个月记录的美元总数是2012年6月)而言,计算出的成员需要足够聪明,以确定2012年6月在日期层次结构中的月份成员是支付的美元总额应从的具体月份。
重要的是,我返回日期维度的年份属性,因为他们希望在表格报告中显示这个成员。
因此,我在计算的度量中包含了以下集合,该度量将根据结果集中返回给客户端的内容获取当前年份的值,并在日期层次结构中向下导航,直到得到有关日历年的最后一天,其有效支付总额如下所示:
Tail(nonempty(descendants([Valuation Date].[DateHierachy].currentmember,4),[Measures].[SaleCount]),1),我的推理是,如果用户在相关报告中选择所有年份,则该特定计算成员每年将获得该日历年的最后一笔非空的已支付美元总额,并允许我从前一年减去该年仅在所涉日历年内发生的已支付美元总额。
现在,上面列出的完整MDX查询在执行时返回正确的数据。然而,执行要花费很长时间,执行时间要超过5-10分钟。基本事实表包含6 400万条记录。
奇怪的是,如果我像这样从第一个计算成员的集合中删除非空()子句,修改后的查询只需30秒即可执行:
With Member [Measures].[CurrentPaidAmount] as
Sum (
Tail(descendants([Valuation Date].[DateHierachy].currentmember,4),1), [Measures].[CurrentTotalPaidAmt]
)我只能假设非空()子句会影响查询的性能,因为计算的成员需要计算日期成员与Measures.SaleCount度量的每个交集。
有没有办法重写上面的查询,以便更好、更快、更有效地执行,最好是在30秒内而不是分钟内完成?
我将默认聚合应用于多维数据集,并将其划分为多个多维数据集分区。
我是MDX的新手,所以我很感谢你的建议。
谢谢您抽时间见我!
发布于 2012-07-11 06:33:15
如果事实表可以存储非累积支付金额,那么您将直接拥有[Measures].[YTDCurrentPaidAmount],它将避免计算[Measures].[CurrentPaidAmount]和[Measures].[PreviousPeriodPaidAmount]。
发布于 2012-07-11 13:44:54
如果将现有的内容混合在一起,有时可以增强对NONEMPTY的反对:
http://cwebbbi.wordpress.com/2009/03/31/existing-and-nonempty/
他在那里变了
COUNT(NONEMPTY(
NONEMPTY(
EXISTING [Customer].[Customer].[Customer].MEMBERS
, [Measures].[Internet Sales Amount])
, ([Measures].[Internet Sales Amount], [Date].[Calendar].CURRENTMEMBER.PREVMEMBER))
)至
COUNT(EXISTING
NONEMPTY(
NONEMPTY(
[Customer].[Customer].[Customer].MEMBERS
, [Measures].[Internet Sales Amount])
, ([Measures].[Internet Sales Amount], [Date].[Calendar].CURRENTMEMBER.PREVMEMBER))
)以八倍的速度增长。
在日期维度上遇到这种情况似乎很奇怪--与其他维度(例如,客户或产品)相比,通常没有太多的日期。你的约会维度有多长时间,你会不必要地深入到未来还是过去?
您可以查看基于使用的优化,设置SSAS Server属性,记录对指定数据库的MDX调用,然后运行向导创建一组基于此的聚合。然后将聚合分配给分区,如果我记得正确的话,则分配“流程索引”.
发布于 2012-07-19 08:42:34
我是MDX的绝对新手,但当我尝试在删除非空子句时解决我自己关于性能问题的问题时,遇到了您问题的潜在解决方案。您可以尝试在计算成员的位置的基本信息窗格中设置非空行为??问候
卡尔
https://stackoverflow.com/questions/11424707
复制相似问题