浅谈SSAS计算中MDX性能改进的几个技巧

来源:互联网 发布:淘宝快修先生怎么样 编辑:程序博客网 时间:2024/05/16 17:42

1.使用半加性度量值替代Calculation 这算是半加性度量值函数的模拟能力之一,但是,有些只在SSAS Enterprise SKU版本中才支持。但是半加性函数操作更快,差不多是MDX脚本两本的速度

 

2.使用一元操作符替代Calculation 服从分配律一元操作符(与位置顺序无关的操作符)一般来说要比同样作用的赋值操作快两倍。那是不是所有的Calculation都要抽取出来,然后用一元操作符替换呢,答案是否定的。例外就是那些不服从分配律的一元操作符(包括*,/或者数字值)。在这种情况下,才会有可能改进性能。

 

3.减小集合计算的大小 当计算值是基于集合,使用NONEMPTY函数减小集合的大小。例如,当计算城市间每个产品的销售平均值,这个查询大约耗时1分46秒,在我的机器上:

with

member measures.x as

avg(existing [Product].[Product].[Product].members*[Customer].[Customer Geography].[City].members, [Measures].[Internet Sales Amount])

select [Date].[Calendar].[Month].members on 0, non empty [Product].[Subcategory].members on 1

from [Adventure Works]

where measures.x

但是添加了NONEMPTY,耗时大约39秒:

with

member measures.x as

avg(existing nonempty( [Product].[Product].[Product].members*[Customer].[Customer Geography].[City].members,[Measures].[Internet Sales Amount]) , [Measures].[Internet Sales Amount])

select [Date].[Calendar].[Month].members on 0, non empty [Product].[Subcategory].members on 1

from [Adventure Works]

where measures.x

避免赋给cell像0, Null, “N/A”, “-“ 这样的值之前翻译的文章已经提过了,AS的引擎在排除空行方面是很高效的。下面的查询使用"-"替换了null值,并且non empty不会排出它们:

with

member measures.x as

iif( not isempty([Measures].[Internet Sales Amount]),[Measures].[Internet Sales Amount],"-")

select descendants([Date].[Calendar].[Calendar Year].&[2004] ) on 0, non empty [Customer].[Customer Geography].[Customer].members on 1

from [Adventure Works]

where measures.x

Non empty操作符不能用来格式化的值上,因此要使用格式化字符串的方式来替换null值,但却排除了空的行,耗时大约是一半的时间: with

member measures.x as

[Measures].[Internet Sales Amount],

FORMAT_STRING = "#.00;(#.00);#.00;-"

select descendants([Date].[Calendar].[Calendar Year].&[2004] ) on 0, non empty [Customer].[Customer Geography].[Customer].members on 1

from [Adventure Works]

where measures.x

有的读者可能已经观察到,上面的两个查询其实是不等效的——第二个查询完全排除了空行。

 

4.计算格式化值的成本 在某些情况下,采用格式化字符串的成本消耗甚至操作了求值本身。这时候就需要对比是否应用格式化属性时两者的执行时间,例如:

select [Measures].[Internet Average Sales Amount] on 0 from [Adventure Works] cell properties value

如果不带格式化的结果明显快的话,可以使用下面的语句实现格式化:

scope([Measures].[Internet Average Sales Amount]); FORMAT_STRING(this) = "currency"; end scope;

执行这个查询(应用了格式化),然后在决定是否采用吧

 

5.使用属性 在SSAS 2000中,当要查找一个集合中哪些成员满足条件通常使用filter函数,例如下面查找男性的顾客:

Filter(Customer.name.Name.members, Customer.name.currentmember.properties(“Gender”) = “Male”)

在SSAS 2005/2008中这样的方式就要避免了,取而代之的是添加一个hierarchy属性Customers.Gender : (Customers.Gender.Male, Measures.Sales)

这个hierarchy属性可以对终端用户隐藏,但是对MDX表达式仍然有效。 下面查询男性客户的平均销售额:

Avg(Customer.Name.Name.members*Customers.Gender.Male, Measures.Sales)

为什么使用.properties会慢呢?因为在获取一个成员的时候每个成员其实都要获取到,这样才能得到property的值,EXISTS更快些是因为直接使用了内部存储结构

 

6.使用IS比较操作符 当比较成员时,比较对象时使用IS,不要像下面这样:

Iif( [Currency Code].currentmember.Name = “USA”], …)

正确的方法是:

Iif( [Currency Code].currentmember IS [Currency Code].[USA], …)

这是因为第一个语句要将成员转型为string,这是要耗时的,而且没有必要

 

7.使用NONEMPTY函数 NONEMPTY函数(SSAS 2005新增的)在提出元组方面进行了优化,因此下面的查询就不可取了:

Filter(Customer.Name.members, not IsEmpty( ([Measures].[Unit Sales], [Product].[Name].[Xbox])

合适的方式是:

NonEmpty (Customer.Name.members, ([Measures].[Unit Sales], [Product].[Name].[Xbox]))

其实Filter(, Not Isempty()) 和NonEmpty(,) 是等效的,现在引擎已经自动做了优化 另外:

Count(Filter([year and month].[Month], Not IsEmpty(([Project Count], [Layer].[Layer].[web])) or Not IsEmpty(([Project Count], [Layer].[Layer].[server]))))

上面的方式也不可取,应该这样:

Count(NonEmpty ([year and month].[Month],{([Project Count], [Layer].[Layer].[web]), ([Project Count], [Layer].[Layer].[server])})

 

8.条件计算 IIF的存在可能会破环引擎的优化,因为优化器不能接受在求值过程中的表达式,这个问题可能以后会解决,但是可以采用一些方案绕过这个问题:

 

9.条件计算和条件域 IIF有时候用于限定应用于集合成员的计算的域,例如:

This = IIF([account].[Account Type].currentmember IS [Account].[Account Type].[Flow], , )

上面的做法不推荐,下面可能会获得更好的性能:

Scope ([Account].[Account Type].[Flow]); This = ; End Scope; Scope ([Account].[Account Type].[Account Type].members – [Account].[Account Type].[Flow]); This = ; End Scope;

 

10.使用ValidMeasure减少计算求值的空间消耗 在SSAS 2005中,每个度量值组都有一个IgnoreUnrelatedDimensions 属性,这个属性定义了如何处理与度量值不相关的维度 --或者忽略这个维度,或者剔除默认成员上的空值。 在定义计算的时候,不要使用这个behavior而是使用ValidMeasuer函数,例如:

scope(leaves([Time]), [Currency].[Currency].members - [Currency].[Currency].[Currency].[USA] Scope [Measures].[store Sales]; This = iif( isempty(validmeasure([Measures].[Exchange Rate])), null, [Measures].[Store Sales]/validmeasure([Measures].[Exchange Rate])); End Scope;

 

11.使用Sum或Aggregate替代求和运算, 避免:

Create Member measures.x as (Sales, Country.USA) + (Sales, Country.Canada) + (Sales, Country.Mexico)…

推荐:

Create Member measures.x as Sum({Country.USA, Country.Canada, Country.Mexico}, Sales)

 

12.在大数据量Crossjoin中多重的Hierarchy 如果可能,尽量使在同一纬度中的hierarchy在一起。为什么呢?因为在引擎内部有一个exists在进行Crossjoin的相邻的集合之间。如果一个来自不用纬度的hierarchy插在两个属于相同纬度的hierarchy之间,exists的行为会变化,就会增加占用的空间,影响性能

 

13.缓存计算结果 在公式引擎内部有一个缓存,用于重用计算结果,但是要进行缓存,这个结果在Cube空间中就要有一个可定地址的单元格或者元组。 例如,一个应用程序在集合中定义了一个比率:一个值除最大值,并且展示为柱状图。 第一种方法:

with

member measures.y as

measures.[unit sales] / max(customers.[name].[name].members, measures.[unit sales])

select measures.y on 0, customers.[name].[name].members on 1

from sales

这个执行大约需要15秒。这个计算其实效率不高,因为最大值其实是不变的,但是每次表达式都要进行求值,下面的查询就要好一些: with

member measures.x as

max(customers.[name].[name].members, measures.[unit sales]) member measures.y as measures.[unit sales] / (measures.x,[Customers].[Customers].[All Customers] )

select measures.y on 0, customers.[name].[name].members on 1

from sales

这个查询不到1秒!性能得到了数量级的提升! 不知道读者有没有注意到一个问题?为什么SSAS表达式中的measure.y必须要在分母中包含[Customers].[Customers].[All Customers] ,换句话说为什么不能这样: with member measures.x as max(customers.[name].[name].members, measures.[unit sales]) member measures.y as measures.[unit sales] / (measures.x) select measures.y on 0, customers.[name].[name].members on 1 from sales 这是因为我们需要引用缓存值。如果[Customers].[Customers].[All Customers]没有写上customer维度的属性,那么单元格会跟着客户名的引用和计算值变化,而计算值每次都要重新求值

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 换驾照色弱被拒怎么办 在上海考驾照贵怎么办 驾驶证有效期过了半年怎么办 资格证脱审2年了怎么办 换驾驶证时眼睛近视了怎么办 违章累计扣12分怎么办 一个违章扣12分怎么办 a1驾照扣3分怎么办 a1驾照扣12分怎么办 吃了毓婷哺乳了怎么办 吃了毓婷后出血怎么办 吃金毓婷喝了水怎么办 白带浓稠浆糊样怎么办 驾校学费不给退怎么办 b1驾证扣了9分怎么办 机动车登记证丢了怎么办 b1驾照扣了9分怎么办 听力正常体检不过关怎么办 做完人流第二天同房了怎么办 医院的票据丢了怎么办 体检人体成分(脂肪缺乏)该怎么办 诊断出右下叶肺炎怎么办 做胸透穿钢圈内衣怎么办 预约不上留学体检怎么办 跨省离职后社保怎么办 开车到成都限号怎么办 月经量多怎么办吃什么 报驾校体检视力不达标怎么办 换驾驶证c1一只眼不合格怎么办 考驾照紧张腿抖怎么办 驾照该换了色弱怎么办 怀孕5个月感冒咳嗽怎么办 怀孕4个月喉咙痛怎么办 怀孕5个多月总是咳嗽尿失禁怎么办 怀孕7个月感冒了怎么办 怀孕7个月感冒喉咙痛怎么办 孕38周感冒咳嗽喉咙痛怎么办 嗓子痛咳嗽有痰怎么办 怀孕6个月了咳嗽怎么办 怀孕了咳嗽黄痰怎么办 科二5次没考过怎么办