雙子星座

           

          商業智能需要站在全局角度考慮問題

          首先看一下下面這個表樣.這個表樣是潤乾的一個示例表樣,接著介紹birt 是如何做的

          5 join dataset

          這個表樣算是報表中最常見的一種需求了,把不同粒度的數據聚合到同一粒度上.

          我們用automobile 表示汽車表, 用houseproperty 表示房產表, 用estate表示土地表,用others 表示其他表.他們都有customerid 來表示客戶名稱.customers 表有customerid 和customername

          1. 用視圖來拼數據

             對于  automobile 聚合使用一個autoview , sql 如下

             select sum(automobile price* quantity) autototal, customerid  from automobile group by customerid

            對于 houseproperty 使用如下view

             select sum( house price * quantity ) housetotal, customerid  from houseproperty group by customerid

            對于 土地和其他也是差不多類型的sql

           

            得到了上面這四個視圖之后, 就把customers 表根據customerid 和其他四個視圖join 起來.

            select customername ,  autototal  , housetotal , estatetotal , othertotal

             from  customers c , automobile a , houseproperty h , estate e , others o

             where 四個視圖和customers的連接條件

           

            由于這個表樣并不涉及到以 汽車,房產,土地, 其他表中的任何一個客戶為主, 所以暫時也不考慮左右連接的問題.

           

          2. 使用Birt 的Joined Data Set

             Birt 提供的Joined Data Set 跟數據庫里面的視圖是差不多的概念,使不過一個是在數據庫內部join 數據,一個是使用Java 循環的方式join 數據.

             跟上面創建視圖一樣,創建四個DataSet , 輸出兩個字段: customerid 和 total.

             然后創建一個Joint Data Set , 把customers 表和 autototal DataSet 按照customerid join起來.這時得到四個字段 customers.customername , customers.customerid  ,  auto DataSet.customerid ,auto DataSet.autotal . 最后我們把這個Joint DataSet 命名為jdataSet1 (代表的是autoDataSet 和 customers 產生的Joint DataSet ).

            然后繼續創建另一個Joint Data Set 把customers 的customerid 和前一步創建的jDataSet1 按照customerid join 起來得到一個第二個Joint DataSet1 ,我們命名為jDataSet2 .

            以此類推,最后我們輸出5個字段: customers.name   ,   auto.total ,  house.total  , estate.total , others.total , 實際輸出可能在customers.customerid 上重復了4次.

           

          上面兩種方式報表的做法主要有兩點差別:

          1. 性能

              如果本身數據庫單獨執行一個視圖的sql 結果比較小,而本身的automobile 表數據量比較大(也就是說一個customer對非常多的automobile 記錄) , 那么使用數據庫視圖就會比較慢. 因為數據庫在嘗試得到4個視圖的結果進行了一些不必要的按照automobiel表的customerid和customers的customerid進 行的比較操作( 如果有索引肯定是對索引進行了多次不必要的讀) ,這時候使用Java的這種循環方式會比較快一點 . 如果本身結構集比較大,那么還是用數據庫本身的排序和join 比較快, 這個道理比較類似于數據庫中如果結構集大于5% 就不要走索引,直接進行全表掃描.只不過這是一個java 版的.

          2. 左右連接的問題

             如果這個表的數據不是以customers里面的數據為主,而是以四個視圖其中的一個為主.這時候要情況可能會比較復雜一些.由于我不太清楚birt 里面joint data set 計算的方式是怎樣的,所以也不太好評論.不過如果不使用joint data set , 就是使用一般的編程的方式.那么按照下面這個思路會比較好:

          a , b , c , d ,e  為customers , automobiles view  (后面簡寫avlist 表示這個集), housetotal view , 里面的指針.  四個view 都已經排好了序.group by 是默認排序的. outlist 表示最后需要的輸出 , row表示最后輸出的一條數據

          for ( 按照主數據循環)  {

              row.customerid = customers.customerid;

              if( customers.customerid == avlist[b].customerid) {

                     outlist[x].autotaol = avlist[b].autotal ;

                     b++

               }

              四個view 同一個判斷方式, 但是每個view 的指針指的是不一樣的.

              最后:   outlistSet . add (outlist[x])

          }

           

          如果數據源本身的數據量也很大,需要輸出的數據也很多,則上面兩種方式都會有性能問題,這時可以考慮商業智能里面的萬金油方式: ETL

           

          3. ETL

              從上面這個表樣看來,可能會有兩個隱含條件.一個是聚合的數據粒度在時間上是月,另一個在銷售地點粒度上是:支行086001-301 , 所以用ETL一開始就聚合數據可能會更好的解決性能問題.另外一個是如果用戶想要排序和過濾數據的話用一個單獨的ETL聚合表也比拼數據的方式好的多.

           

          這篇文章的目的并不只是想解釋一個做表的問題,而是說明商業智能的一些問題不光需要站在一個獨立的角度思考,有些問題本身可能隨著環境的一些變化而 采取對應的措施,比如上面為了解決排序,過濾,左右連接,性能問題都需要從不同的角度來考慮問題.有時候可能一個做表的問題不光只是要限定在sql 或某個報表軟件的本身,有時候某個ETL問題可能不關只是ETL就能解決的,隨著情況的復雜可能需要從整個商業智能的全局來進行考慮,商業智能越來越傾向 與多個解決方法的融合.

          本文原文在 http://www.gemini5201314.net

          如果你對ETL中性能優化問題有興趣的話,也可以查看另一篇關于在ETL中性能優化要站在全局的角度,而不是只在數據庫角度的文章.

          posted on 2008-03-21 12:16 gemini 閱讀(387) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          導航

          統計

          常用鏈接

          留言簿(3)

          隨筆檔案

          相冊

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宁都县| 酒泉市| 沛县| 新化县| 南乐县| 游戏| 徐水县| 崇阳县| 隆林| 无为县| 宜章县| 开远市| 溧阳市| 长葛市| 吉首市| 平安县| 海伦市| 新宁县| 全南县| 霍邱县| 福鼎市| 阿拉善右旗| 肇庆市| 泰顺县| 肇州县| 邢台市| 察雅县| 渑池县| 凉城县| 革吉县| 文成县| 哈密市| 泰和县| 皋兰县| 绥棱县| 平舆县| 香港 | 白玉县| 鄂温| 桐城市| 齐河县|