報表性能優(yōu)化方案之報表取數(shù)
Posted on 2015-09-21 10:29 FineReport——報表技術(shù)領(lǐng)跑者 閱讀(302) 評論(0) 編輯 收藏 所屬分類: Java報表使用心得1. 取數(shù)原理
設(shè)計器拼出最終的SQL,將SQL語句傳給數(shù)據(jù)庫,數(shù)據(jù)庫執(zhí)行,將數(shù)據(jù)返回給設(shè)計器。
由于計算過程首先要通過SQL語句從數(shù)據(jù)庫中取數(shù)據(jù),我們可以通過控制數(shù)據(jù)量的大小和對數(shù)據(jù)的提前預(yù)處理來提高報表的性能。下面是一些優(yōu)化的方法。
2. 優(yōu)化SQL
FineReport報表的數(shù)據(jù)集采用的是表模型,也就是說通過SQL這種DSL語言,從數(shù)據(jù)庫通過簡單查詢或各種組合關(guān)聯(lián)查詢得到一個關(guān)系表,而這部分SQL查詢根據(jù)各種數(shù)據(jù)庫產(chǎn)商長時間的優(yōu)化(比如建立索引),已經(jīng)非常成熟。數(shù)據(jù)集一般要通過FineReport報表模型的復(fù)雜處理才能生成最終的表樣。因此,從數(shù)據(jù)庫SQL查詢?nèi)〕鰯?shù)據(jù)量越少,F(xiàn)ineReport報表模型需要做的復(fù)雜處理和計算就越少,所花的時間和內(nèi)存就少,從而可以提高性能。
2.1 SQL語句取具體的字段
我們一般會用select * from 這樣的形式將一個數(shù)據(jù)庫表中所有的字段都取出來,而其中一些字段是報表中不需要用到的,例如報表中只需要用到三個字段,但是數(shù)據(jù)庫中實際的表有十個字段,一些初學(xué)者習(xí)慣性的用select * from table1,這樣相當于把十個字段的數(shù)據(jù)都取到報表服務(wù)器端,增加了報表服務(wù)器端的內(nèi)存占用以及減慢了運算速度,所以SQL語句中盡量不要用“*”號,而是寫上具體的字段,能夠減少報表服務(wù)器端的內(nèi)存占用,加快報表的運算速度。
2.2 SQL中直接分組代替報表中分組
一些匯總類型的報表,例如制作一張訂單總額的表,可能會從訂單明細表中取出大量的數(shù)據(jù)記錄,然后進行數(shù)據(jù)匯總,即進行分組聚集運算,報表計算過程中我們可以在SQL中提前進行一次分組聚集,能夠大大減少取到的報表服務(wù)器的記錄數(shù),加快取數(shù)和報表運算的速度。
SQL語句:SELECT 成本價,類別ID FROM 產(chǎn)品
從數(shù)據(jù)庫中選擇如上兩個字段,然后根據(jù)類別ID進行成本價的匯總,此時數(shù)據(jù)庫返回給報表處理的數(shù)據(jù)就有77條。如下:
優(yōu)化的SQL語句:SELECT sum(成本價),類別ID FROM 產(chǎn)品 group by 類別ID
經(jīng)過SQL優(yōu)化后,報表需要處理的數(shù)據(jù)就只剩8條了。如下:
優(yōu)化分析:
第一種做法,不僅僅取到報表服務(wù)器上記錄數(shù)多了,取數(shù)速度慢,而且報表模型需要對表數(shù)據(jù)列進行分組運算,增加了報表運行時間;
第二種做法,數(shù)據(jù)庫雖然要進行分組運算,但是數(shù)據(jù)庫中有索引,運算速度快,且取到報表服務(wù)器端的記錄數(shù)大大減少,取數(shù)速度大大加快,因此在報表模型進行分組運算的時候只要對很少的記錄數(shù)進行,報表的運算速度大大加快了。
實驗結(jié)果以及分析表明,第二種做法的性能遠優(yōu)于第一種。所以,分組應(yīng)該盡量在sql里進行。
2.3 SQL中直接排序代替報表中排序
報表計算過程中很多時候需要對數(shù)據(jù)進行排序,雖然排序運算可以在報表端進行,不過我們還是建議在SQL中提前將數(shù)據(jù)排序,這是因為數(shù)據(jù)庫中索引功能,通常是C/C++語言(往往在效率上比Java好)寫的,會使得排序運算的速度很快。
2.4 SQL中直接過濾代替報表中過濾
報表計算過程中很多時候并不需要對表中的所有記錄進行操作,而只是需要對部分滿足條件的記錄進行操作,雖然可以在報表設(shè)計器中對數(shù)據(jù)過濾,不過我們建議在SQL中對數(shù)據(jù)提前過濾,這樣數(shù)據(jù)庫返回的數(shù)據(jù)就減少了,既加快了取數(shù)速度,也加快了報表的運算速度。
3. 使用視圖、存儲過程
視圖是由SELECT語句組成的查詢定義的虛擬表,由一張或多張數(shù)據(jù)庫實際的表中的數(shù)據(jù)組成的,從數(shù)據(jù)庫系統(tǒng)外部來看,視圖就如同一張表一樣。
存儲過程通過流控制與SQL語句,可以對數(shù)據(jù)進行強大的運算與處理,對于業(yè)務(wù)比較復(fù)雜的應(yīng)用,常常需要將原始數(shù)據(jù)通過存儲過程處理后再供報表使用。另外存儲過程運行前,數(shù)據(jù)庫會對其進行語法和句法的分析,并進行優(yōu)化,這種已經(jīng)編譯好的存儲過程極大地改善SQL語句的性能。在報表端也只需要書寫較短的調(diào)用語句來獲得結(jié)果,從而降低網(wǎng)絡(luò)的通信量。
所以表與表的連接、復(fù)雜的SQL盡量在數(shù)據(jù)庫中使用視圖或者存儲過程直接進行,這樣將復(fù)雜的SQL語句直接保存于數(shù)據(jù)庫服務(wù)器端(數(shù)據(jù)庫本身會對SQL語句進行語法分析并進行優(yōu)化),在報表設(shè)計器端就不需要寫大段的SQL語句而是直接調(diào)用視圖或存儲過程了,一方面減少網(wǎng)絡(luò)傳輸量,減輕數(shù)據(jù)庫的壓力,另一方面加快了報表的運算速度。