`

Mondrian解析MDX成sql语句的分析与整理

阅读更多

    不久前, 在同事的努力下,他找到了如何设置使Mondrian 解析mdxsql 语句在控制台打印出来,这样就可以方便地查看你的mdx 查询语句执行的详细过程。我结合自己的demo 测试了一下,将其步骤记录下来,并将其如何解析的过程也整理和总结了一遍,希望对正在学习mdx 的朋友有些帮助。

 

在控制台输出 mdx 被解析出来的对应的 sql 语句步骤:

首先, WEB-INF 下添加一个 mondrian.properties 文件,内容如下:

 

# Allow the use of aggregates

mondrian.rolap.aggregates.Use= true

mondrian.rolap.aggregates.Read= true

mondrian.native.topcount.enable= true

mondrian.native.filter.enable= true

 

# mondrian.properties

mondrian.result.limit= 50000

 

# For XML/A JSPs

mondrian.rolap.generate.formatted.sql= true

 

说明:你可要是怕敲代码,就在 mondrian 的源文件的 lib 目录下找到 mondrian.war 这个包,改下扩展名( .zip )将其解压缩开,在 WEB-INF 目录下找到 mondrian.properties 这个文件,并将里面的最后一句删除, mondrian.test.connectString=Provider=mondrian;Jdbc=jdbc:odbc:MondrianFoodMart;JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver;Catalog=/WEB-INF/queries/FoodMart.xml;

然后加上以下这句话即可: mondrian.rolap.generate.formatted.sql= true

 

 

其次, 同时,将 mondrian.properties 文件拷到你的 tomcat 安装目录下的 bin 文件夹里

 

最后, 在你项目的直接目录 src 下新建一个 log4j.properties 文件,内容如下:

 

# Set root logger level to DEBUG and its only appender to MONDRIAN.

log4j.rootLogger= WARN, MONDRIAN

 

# MONDRIAN is set to be a ConsoleAppender.

log4j.appender.MONDRIAN= org.apache.log4j.ConsoleAppender

 

# MONDRIAN uses PatternLayout.

log4j.appender.MONDRIAN.layout= org.apache.log4j.PatternLayout

log4j.appender.MONDRIAN.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n

 

# Trace MDX and SQL statements

log4j.category.mondrian.sql= DEBUG

 

(说明: log4j.properties 文件的内容设置你可以参看你 mondrian 安装目录下的 D:/mondrian-3.2.0.13661/doc/ 文件,打开 index.html 页面

 

选中 Configuration ,进入页面configuration.html.

 

再选中 MDX and SQL Statement Logging , 进去,里面介绍了详细步骤!以及 log4j.properties 文件的内容。)

 

 

现在运行项目,在你的控制台就会输出相应的 sql 语句了。

下面就是 Mondrian 解析的过程:

 

 

 

解析过程 :

从控制台输出的信息可以分析出: mondrian 到底执行了那些 sql 语句 .

比如,我想做一个商品向下钻取的例子:

在当前页面点击“ All Products

则控制台输出为:


1.>
22157 [http-8080-1] DEBUG mondrian.sql  - 1: SqlMemberSource.getMemberChildren: executing sql [

select

    `producttype`.`proTypeId` as `c0`,

    `producttype`.`proTypeName` as `c1`

from

    `product` as `product`,

    `producttype` as `producttype`

where

    `product`.`proTypeId` = `producttype`.`proTypeId`

group by

    `producttype`.`proTypeId`,

    `producttype`.`proTypeName`

order by

    ISNULL(`producttype`.`proTypeId`), `producttype`.`proTypeId` ASC

]

22203 [http-8080-1] DEBUG mondrian.sql  - 1: , exec 46 ms

22219 [http-8080-1] DEBUG mondrian.sql  - , exec+fetch 62 ms, 4 rows

*********************************************************************

 

2.> 22219 [http-8080-1] DEBUG mondrian.sql  - 2: RolapStar.Column.getCardinality: executing sql [

select

    count(distinct `producttype`.`proTypeId`) as `c0`

from

    `producttype` as `producttype`

]

22235 [http-8080-1] DEBUG mondrian.sql  - 2: , exec 16 ms

22235 [http-8080-1] DEBUG mondrian.sql  - , exec+fetch 16 ms, 1 rows

*********************************************************************

 

3.> 22235 [http-8080-1] DEBUG mondrian.sql  - 3: Segment.load: executing sql [

select

    `producttype`.`proTypeId` as `c0`,

    sum(`sale`.`number`) as `m0`,

    sum((unitPrice*number)) as `m1`

from

    `producttype` as `producttype`,

    `product` as `product`,

    `sale` as `sale`

where

    `sale`.`proId` = `product`.`proId` and

    `product`.`proTypeId` = `producttype`.`proTypeId`

group by

    `producttype`.`proTypeId`

]

22250 [http-8080-1] DEBUG mondrian.sql  - 3: , exec 15 ms

22250 [http-8080-1] DEBUG mondrian.sql  - , exec+fetch 15 ms, 4 rows

 

如果在上个页面的基础上再点击“ All Products ”下的子集“ Electrical Equipments ”,

如下图片所示:

 

 

则控制台打印出的结果是:

 

4.> 2840907 [http-8080-2] DEBUG mondrian.sql  - 4: SqlMemberSource.getMemberChildren: executing sql [

select

    `product`.`proId` as `c0`,

    `product`.`proName` as `c1`

from

    `product` as `product`,

    `producttype` as `producttype`

where

    `product`.`proTypeId` = `producttype`.`proTypeId` and

    (`producttype`.`proTypeId` = '1')

group by

    `product`.`proId`,

    `product`.`proName`

order by

    ISNULL(`product`.`proId`), `product`.`proId` ASC

]

2840907 [http-8080-2] DEBUG mondrian.sql  - 4: , exec 0 ms

2840907 [http-8080-2] DEBUG mondrian.sql  - , exec+fetch 0 ms, 3 rows

*********************************************************************

 

5.> 2840907 [http-8080-2] DEBUG mondrian.sql  - 5: RolapStar.Column.getCardinality: executing sql [

select

    count(distinct `product`.`proId`) as `c0`

from

    `product` as `product`

]

2840907 [http-8080-2] DEBUG mondrian.sql  - 5: , exec 0 ms

2840907 [http-8080-2] DEBUG mondrian.sql  - , exec+fetch 0 ms, 1 rows

 

*********************************************************************

 

6.> 2840907 [http-8080-2] DEBUG mondrian.sql  - 6: Segment.load: executing sql [

select

    `product`.`proId` as `c0`,

    sum(`sale`.`number`) as `m0`,

    sum((unitPrice*number)) as `m1`

from

    `product` as `product`,

    `sale` as `sale`

where

    `sale`.`proId` = `product`.`proId` and

    `product`.`proId` in ('1', '2', '9')

group by

    `product`.`proId`

]

2840922 [http-8080-2] DEBUG mondrian.sql  - 6: , exec 15 ms

2840922 [http-8080-2] DEBUG mondrian.sql  - , exec+fetch 15 ms, 3 rows

 

 

由上面的步骤 1>,2>,3>; 以及后面 4>,5>,6> 我们就可以得出:

mondrian drill down (向下钻取)的时候一般执行 3 sql .

 

而每个 sql 的语法格式大概如下 :
*****: executing sql [
执行的 sql ]

***** : exec 时间

*****: exec + fetch 时间 取得的数据行数 .
其中前面的 ***** 部分是看你执行的那些操作,



第一个 sql   取得 dimension 子元素的名称 : 一般通过如下 sql 取得(即我上面所说的第 1> ,第 4> 步) :
SqlMemberSource.getMemberChildren: executing sql [

select

    `producttype`.`proTypeId` as `c0`,

    `producttype`.`proTypeName` as `c1`

from

    `product` as `product`,

    `producttype` as `producttype`

where

    `product`.`proTypeId` = `producttype`.`proTypeId`

group by

    `producttype`.`proTypeId`,

    `producttype`.`proTypeName`

order by

    ISNULL(`producttype`.`proTypeId`), `producttype`.`proTypeId` ASC

]


第二个 sql   取得左边的 dimension 的一个层次结构下的子元素的数目 . 比如 All Products 下就有四个 . sql 语句就如我上面所列出的第 2>, 5> 步格式,在此就不再再拷贝下来了。


第三个 sql 取得对应 dimension 的实际数据 , sql 语句就像我上面所列出的第 3>, 6> 步格式,在此也不再拷贝下来了。

 

假如你想 mdx sql 一起对比着看,可以在 log4j.properties 里面写入:

log4j.category.mondrian.mdx= MONDRIAN

log4j.category.mondrian.sql= DEBUG

 

这样控制台输出的结果就如下面的这种格式:

6297 [http-8080-1] DEBUG mondrian.mdx  - 0: select {[Measures].[Number], [Measures].[Total Sale]} ON COLUMNS,

  {[Product Category].[All Products]} ON ROWS

from [Sales]

 

6562 [http-8080-1] DEBUG mondrian.sql  - 0: Segment.load: executing sql [

select

    sum(`sale`.`number`) as `m0`,

    sum((unitPrice*number)) as `m1`

from

    `sale` as `sale`

]

6578 [http-8080-1] DEBUG mondrian.sql  - 0: , exec 16 ms

 

 


By the way, 供大家交流Pentaho的圈子,里面可以共享有关pentahoBI平台学习的资料,期待您的加入! http://pentahofrends.group.iteye.com/

 

 

9
1
分享到:
评论
2 楼 lingyun6100 2014-10-31  
按楼主说的操作了 还是没有打印出mdx语句,很郁闷。
1 楼 鱼丸粗面 2012-03-28  
楼主讲得是底层实现吧,学习中。。。

相关推荐

Global site tag (gtag.js) - Google Analytics