商業智能研究(十五) materialized view+dimension提高mondrian性能
materialized view+dimension提高mondrian性能
按著上一篇的步驟部署好了mondrian 之后
進入數據庫,修改所有以agg開頭的表格,把它們重命名或者或者drop掉,下一篇我會解釋為什么的.
修改 WEB-INF / mondrian.properties 文件,加上如下兩個key
mondrian.trace.level=1
mondrian.debug.out.file=e:/mondrianfoodmart.log
然后把mondrian.properties文件copy 到tomcat 的 bin 目錄下重新啟動tomcat.
打開瀏覽器進入JPivot with arrows 的example .
一直drill down product. All Products -> Drink -> Alcoholic Beverages -> Beer and Wine -> Beer -> Good -> Good Imported Beer
你會在e:/ 下找到一個mondrianfoodmart.log 的文件,打開這個文件,你會看到類似與下面的語句 :
SqlMemberSource.getMemberChildren: executing sql [select "time_by_day"."the_year" as "c0" from "time_by_day" "time_by_day" group by "time_by_day"."the_year" order by "time_by_day"."the_year" ASC], exec 31 ms, exec+fetch 31 ms, 2 rows
你可以把這個文件copy一份到其他地方,我們就是要分析這個文件,來知道mondrian到底執行了那些sql語句.
它的語法格式大概如下:
**** executing sql [ 執行的sql ] exec 時間 , exec + fetch 時間 , 取得的數據行數.
其中前面的**** 部分是看你執行的那些操作,
mondrian 做drill down 的時候一般執行3 個 sql ,
1 . 取得左邊的dimension 的一個層次結構下的子元素的數目.比如All Products 下就有三個: Drink , Food , Non-Consumable
一般通過如下sql取得 :
SELECT COUNT(DISTINCT "product_class"."product_family") AS "c0" FROM "product_class" "product_class";
2 . 取得dimension 子元素的名稱 : 象如下sql :
SELECT "product_class"."product_department" AS "c0"
FROM "product" "product", "product_class" "product_class"
WHERE "product"."product_class_id" = "product_class"."product_class_id"
AND "product_class"."product_family" = 'Drink'
GROUP BY "product_class"."product_department"
ORDER BY "product_class"."product_department" ASC;
3 . 取得對應dimension的實際數據 , 象如下sql:
SELECT "time_by_day"."the_year" AS "c0", "product_class"."product_family" AS "c1",
SUM("sales_fact_1997"."store_sales") AS "m0", SUM("sales_fact_1997"."store_cost") AS "m1"
FROM "time_by_day" "time_by_day", "sales_fact_1997" "sales_fact_1997", "product_class" "product_class",
"product" "product"
WHERE "sales_fact_1997"."time_id" = "time_by_day"."time_id"
AND "time_by_day"."the_year" = 1997
AND "sales_fact_1997"."product_id" = "product"."product_id"
AND "product"."product_class_id" = "product_class"."product_class_id"
GROUP BY "time_by_day"."the_year",
"product_class"."product_family";
打開你的文本編輯器,我用的是vi , 執行兩個替換命令
1 . :%s/^.*executing sql \[//g
2 . :%s/\], exec.*$/;/g
第一個命令是將所有' executing sql [ '之前的字符串去掉,第二個命令是將所有 ' ] exec ' 之后的字符串換成 ;
這個時候就只剩下可以執行的sql 了.把里面的內容copy 到你的sql 編輯器里面,我用的是oracle 官方的sql developer , 把它format一下,然后依次執行一下里面的所有sql ,看一下結果.
通過研究這個結果,我們可以確定product 的層次關系:
1 . 在product表里面,沒有使用聯合主鍵來確定product的唯一性,而是使用 product_id 作為主鍵,其中product_name 也是唯一的,對應 : Good Imported Beer , Good Light Beer .
2 . product_name 上一級是brand_name ,對應 : Good , Pearl ,Portsmounth , Top Measure , Walrus
3 . brand_name 的上一級是subcategory ,它在product_class表里面,product 和 product_class 通過product_class_id 鏈接起來,同樣的,product_class 表沒有用聯合主鍵來定義唯一性,而是用product_class_id 來做主鍵,其中product_subcategory 是唯一的,跟product_class_id 是一一對應的. subcategory 有:Beer , Wine
4 . product_subcategory的上一級是category ,對應 : Beer and Wine .
5 . category的上一級是department , 對應 : Alcoholic Beverages , Beverages , Dairy .
6 . department的上一級是family ,也是最頂級了 , 對應 : Drink , Food ,Non-Consumable .
在我的例子中,我將使用Time 和 Product 來做Dimension , 應為他們比較有代表性,
time_by_day 表中,有十個column ,最后一個 fiscal_period 沒有用.
1 . time_id 這個表中的主鍵
2 . the_date 數據類型是timestamp,是唯一的,其中定義了從1997年1月1日開始到1998年12月31日的所有日期.
3 . the_day 定義的星期,比如 Monday .
4 . the_month 定義的月份,比如September
5 . the_year 年份 , 1997 和 1998 .
6 . day_of_month 月份中的日期, 比如23代表那個月份的23號 .
7 . week_of_year 一年中的第幾個星期,比如40 代表一年中的第40個星期
8 . month_of_year 一年中的第幾個月,比如9 代表第九個月,
9 . quarter , 季度 .
Time dimension 建立在time_by_day 表上,其中可以用多個層級來表示Time的level 關系,比如the_year -> quarter -> the_month -> the_date ,或者year -> week_of_year -> the_day -> the_date .
Product Dimension 建立在product 和 product_class 表上,是跨表的dimension
product.product_id 主鍵
product.product_name 最低的level .
product.brand_name 第二level .
product.product_class_id 映射到product_class 的外鍵
product 其他colun 都是非主屬性了.
product_class.product_class_id 主鍵
product_class.product_subcategory 唯一的,對應product_class_id 第三level.
product_class.product_category 第四level.
product.product_department 第五level.
product.product_family 第六level.
下篇接著寫dimension + materialized view .
有哪位朋友可以推薦一下武漢的公司,最好是小一點的公司(大公司估計自己水品有限),如果有需要J2EE開發方向的工作職位的話,推薦一下, jj12tt@yahoo.com.cn ,先謝謝了.
進入數據庫,修改所有以agg開頭的表格,把它們重命名或者或者drop掉,下一篇我會解釋為什么的.
修改 WEB-INF / mondrian.properties 文件,加上如下兩個key
mondrian.trace.level=1
mondrian.debug.out.file=e:/mondrianfoodmart.log
然后把mondrian.properties文件copy 到tomcat 的 bin 目錄下重新啟動tomcat.
打開瀏覽器進入JPivot with arrows 的example .
一直drill down product. All Products -> Drink -> Alcoholic Beverages -> Beer and Wine -> Beer -> Good -> Good Imported Beer
你會在e:/ 下找到一個mondrianfoodmart.log 的文件,打開這個文件,你會看到類似與下面的語句 :
SqlMemberSource.getMemberChildren: executing sql [select "time_by_day"."the_year" as "c0" from "time_by_day" "time_by_day" group by "time_by_day"."the_year" order by "time_by_day"."the_year" ASC], exec 31 ms, exec+fetch 31 ms, 2 rows
你可以把這個文件copy一份到其他地方,我們就是要分析這個文件,來知道mondrian到底執行了那些sql語句.
它的語法格式大概如下:
**** executing sql [ 執行的sql ] exec 時間 , exec + fetch 時間 , 取得的數據行數.
其中前面的**** 部分是看你執行的那些操作,
mondrian 做drill down 的時候一般執行3 個 sql ,
1 . 取得左邊的dimension 的一個層次結構下的子元素的數目.比如All Products 下就有三個: Drink , Food , Non-Consumable
一般通過如下sql取得 :
SELECT COUNT(DISTINCT "product_class"."product_family") AS "c0" FROM "product_class" "product_class";
2 . 取得dimension 子元素的名稱 : 象如下sql :
SELECT "product_class"."product_department" AS "c0"
FROM "product" "product", "product_class" "product_class"
WHERE "product"."product_class_id" = "product_class"."product_class_id"
AND "product_class"."product_family" = 'Drink'
GROUP BY "product_class"."product_department"
ORDER BY "product_class"."product_department" ASC;
3 . 取得對應dimension的實際數據 , 象如下sql:
SELECT "time_by_day"."the_year" AS "c0", "product_class"."product_family" AS "c1",
SUM("sales_fact_1997"."store_sales") AS "m0", SUM("sales_fact_1997"."store_cost") AS "m1"
FROM "time_by_day" "time_by_day", "sales_fact_1997" "sales_fact_1997", "product_class" "product_class",
"product" "product"
WHERE "sales_fact_1997"."time_id" = "time_by_day"."time_id"
AND "time_by_day"."the_year" = 1997
AND "sales_fact_1997"."product_id" = "product"."product_id"
AND "product"."product_class_id" = "product_class"."product_class_id"
GROUP BY "time_by_day"."the_year",
"product_class"."product_family";
打開你的文本編輯器,我用的是vi , 執行兩個替換命令
1 . :%s/^.*executing sql \[//g
2 . :%s/\], exec.*$/;/g
第一個命令是將所有' executing sql [ '之前的字符串去掉,第二個命令是將所有 ' ] exec ' 之后的字符串換成 ;
這個時候就只剩下可以執行的sql 了.把里面的內容copy 到你的sql 編輯器里面,我用的是oracle 官方的sql developer , 把它format一下,然后依次執行一下里面的所有sql ,看一下結果.
通過研究這個結果,我們可以確定product 的層次關系:
1 . 在product表里面,沒有使用聯合主鍵來確定product的唯一性,而是使用 product_id 作為主鍵,其中product_name 也是唯一的,對應 : Good Imported Beer , Good Light Beer .
2 . product_name 上一級是brand_name ,對應 : Good , Pearl ,Portsmounth , Top Measure , Walrus
3 . brand_name 的上一級是subcategory ,它在product_class表里面,product 和 product_class 通過product_class_id 鏈接起來,同樣的,product_class 表沒有用聯合主鍵來定義唯一性,而是用product_class_id 來做主鍵,其中product_subcategory 是唯一的,跟product_class_id 是一一對應的. subcategory 有:Beer , Wine
4 . product_subcategory的上一級是category ,對應 : Beer and Wine .
5 . category的上一級是department , 對應 : Alcoholic Beverages , Beverages , Dairy .
6 . department的上一級是family ,也是最頂級了 , 對應 : Drink , Food ,Non-Consumable .
在我的例子中,我將使用Time 和 Product 來做Dimension , 應為他們比較有代表性,
time_by_day 表中,有十個column ,最后一個 fiscal_period 沒有用.
1 . time_id 這個表中的主鍵
2 . the_date 數據類型是timestamp,是唯一的,其中定義了從1997年1月1日開始到1998年12月31日的所有日期.
3 . the_day 定義的星期,比如 Monday .
4 . the_month 定義的月份,比如September
5 . the_year 年份 , 1997 和 1998 .
6 . day_of_month 月份中的日期, 比如23代表那個月份的23號 .
7 . week_of_year 一年中的第幾個星期,比如40 代表一年中的第40個星期
8 . month_of_year 一年中的第幾個月,比如9 代表第九個月,
9 . quarter , 季度 .
Time dimension 建立在time_by_day 表上,其中可以用多個層級來表示Time的level 關系,比如the_year -> quarter -> the_month -> the_date ,或者year -> week_of_year -> the_day -> the_date .
Product Dimension 建立在product 和 product_class 表上,是跨表的dimension
product.product_id 主鍵
product.product_name 最低的level .
product.brand_name 第二level .
product.product_class_id 映射到product_class 的外鍵
product 其他colun 都是非主屬性了.
product_class.product_class_id 主鍵
product_class.product_subcategory 唯一的,對應product_class_id 第三level.
product_class.product_category 第四level.
product.product_department 第五level.
product.product_family 第六level.
下篇接著寫dimension + materialized view .
有哪位朋友可以推薦一下武漢的公司,最好是小一點的公司(大公司估計自己水品有限),如果有需要J2EE開發方向的工作職位的話,推薦一下, jj12tt@yahoo.com.cn ,先謝謝了.