zoukankan      html  css  js  c++  java
  • MDX优化Set操作

    MDX优化Set操作—SUM中的CrossJoin

    1. 优化Set操作的关键在于:把大的SET操作变成小的SET操作。
    2. 由于CrossJoin代价(CPU、内存)巨大,所以最好用其他操作代替CrossJoin操作。

    SUM中的CrossJoin
    作者认为:要避免SUM一个包含多个CrossJoin的Set,你可以用其他的操作(比如嵌套SUM)进行替换。据此,我测试了一下
    两组语句:
    WITH MEMBER MEASURES.ABC AS 
    Sum (
        CrossJoin (
            Descendants (
                
    [Customer].[Customer Geography].CurrentMember,
                
    [Customer].[Customer Geography].[State-Province]
            ),
            Crossjoin (
                Descendants (
                    
    [Date].[Calendar].CurrentMember,
                    
    [Date].[Calendar].[Date]
                ),
                Descendants (
                    
    [Product].[Product Categories].CurrentMember,
                    
    [Product].[Product Categories].[Product Name]
                )
            )
        )
        ,[Measures].[Internet Sales Amount]-[Measures].[Internet Tax Amount]

      )
    SELECT MEASURES.ABC ON 0 ,
    [Customer].[Customer Geography].[Country].Members *  
    [Date].[Calendar].[Calendar Year].MEMBERS * 
    [Product].[Product Categories].[Category].MEMBERS
    ON 1
    FROM [Adventure Works]
    WITH MEMBER MEASURES.ABC AS 
    Sum (
        Descendants (
            
    [Customer].[Customer Geography].CurrentMember,
            
    [Customer].[Customer Geography].[State-Province]
        ),        
        
    SUM(
            Descendants (
                
    [Product].[Product Categories].CurrentMember,
                
    [Product].[Product Categories].[Product Name]
            ),
            
    SUM(
                Descendants (
                    
    [Date].[Calendar].CurrentMember,
                    
    [Date].[Calendar].[Date]
                )        
                ,[Measures].[Internet Sales Amount]-[Measures].[Internet Tax Amount]

            )                
        )    
    )
    SELECT MEASURES.ABC ON 0 ,
    {
    [Customer].[Customer Geography].[Country].Members} *  
    [Date].[Calendar].[Calendar Year].Members * 
    [Product].[Product Categories].[Category].Members
    ON 1
    FROM [Adventure Works]

    以上语句中,作者认为第一个语句慢于第二个语句(理由是嵌套的SUM每次操作的SET更小),可实际的结果(测了10次)恰恰相反,第一个语句平均花费的时间51.654秒,而第二个语句平均花费的时间在55.912秒,这是何故呢?此外,书中认为在第二个语句的嵌套SUM中,如果把大的Set放在里面,这样会快一些。也就是说下面的语句比上面第二个语句要慢5%-20%。

    WITH MEMBER MEASURES.ABC AS 
    Sum (
        Descendants (
            
    [Date].[Calendar].CurrentMember,
            
    [Date].[Calendar].[Date]
        ),
        
    SUM(
            Descendants (
                
    [Product].[Product Categories].CurrentMember,
                
    [Product].[Product Categories].[Product Name]
            ),      
            
    SUM(
            Descendants (
                
    [Customer].[Customer Geography].CurrentMember,
                
    [Customer].[Customer Geography].[State-Province]
            ),    
                
    [Measures].[Internet Sales Amount]-[Measures].[Internet Tax Amount]        )                
        )    
    )
    SELECT MEASURES.ABC ON 0 ,
    {
    [Customer].[Customer Geography].[Country].Members} *  
    [Date].[Calendar].[Calendar Year].Members * 
    [Product].[Product Categories].[Category].Members
    ON 1
    FROM [Adventure Works]


     

    以上测试语句中,关于[Date].[Calendar].[Date]的Set其Turple个数在365左右,关于[Product].[Product Categories].[Product Name]的Set其Turple个数在几十个左右,而关于[Customer].[Customer Geography].[State-Province]的Set其成员个数大多在十几个左右

    经过测试发现上面这条语句平均时间在57.858秒。也就是说,测试结果和书中的观点是一致的,只是幅度没有那么大。此外,我还尝试了一下这样的写法。

    WITH 
    MEMBER MEASURES.ABC 
    AS 
    Sum (
        
        CrossJoin (
            Descendants (
                
    [Customer].[Customer Geography].CurrentMember,
                
    [Customer].[Customer Geography].[State-Province]
            ),
            Crossjoin (
                Descendants (
                    
    [Date].[Calendar].CurrentMember,
                    
    [Date].[Calendar].[Date]
                ),
                Descendants (
                    
    [Product].[Product Categories].CurrentMember,
                    
    [Product].[Product Categories].[Product Name]
                )
            )
        ) 
    AS MYABC

        ,
    [Measures].[Internet Sales Amount]
    )
    -
    Sum (    
        MYABC
        ,
    [Measures].[Internet Tax Amount]
    )
    SELECT MEASURES.ABC ON 0 ,
    [Customer].[Customer Geography].[Country].Members *  
    [Date].[Calendar].[Calendar Year].MEMBERS * 
    [Product].[Product Categories].[Category].MEMBERS
    ON 1
    FROM [Adventure Works]

    上面语句的不同之处在于,把要计算的内容分散开来了,令人惊异的是,这个语句只要2-3秒种就能运行完成。


    总结
    由上面两次测试我们可以得出以下结论:
    1)SUM中的CrossJoin并不一定会降低速度,书中的观点可能是错误的。看来MDX解析器对CrossJoin有很多有优化,在上面的测试中CrossJoin比嵌套的SUM要快8%左右。
    2)嵌套SUM中,把大的SET放在里层的SUM中,这样速度能够快一些。上面的测试中,把小的Set放在里层比把大的Set放在里层慢3.5%。
    3)在做SUM等统计计算时,如果能够把计算项分解到每个单独的Measure,这个时候性能提升非常明显,速度将会大大提高。上面的测试中,速度提高了20多倍。

  • 相关阅读:
    Codeforces Round #551 (Div. 2) F. Serval and Bonus Problem (DP/FFT)
    Codeforces Round #551 (Div. 2) E. Serval and Snake (交互题)
    BZOJ 5495: [2019省队联测]异或粽子 (trie树)
    洛谷【P2669】NOIP2015普及组 T1金币
    解决Win 10上SSD缓慢问题
    如何保障数据安全
    一个网工的linux学习过程
    JS实现select去除option的使用注意事项
    codevs1506传话(kosaraju算法)
    我的园子
  • 原文地址:https://www.cnblogs.com/Ammy/p/1706477.html
Copyright © 2011-2022 走看看