当前位置: 代码迷 >> SQL >> Mondrian解析MDX成sql话语的分析与整理
  详细解决方案

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

热度:116   发布时间:2016-05-05 13:20:29.0
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>步格式,在此也不再拷贝下来了。

?

假如你想mdxsql一起对比着看,可以在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/

?

?

1 楼 鱼丸粗面 2012-03-28  
楼主讲得是底层实现吧,学习中。。。