1. 取數原理
設計器拼出最終的SQL,將SQL語句傳給數據庫,數據庫執行,將數據返回給設計器。
由于計算過程首先要通過SQL語句從數據庫中取數據,我們可以通過控制數據量的大小和對數據的提前預處理來提高報表的性能。下面是一些優化的方法。
2. 優化SQL
FineReport報表的數據集采用的是表模型,也就是說通過SQL這種DSL語言,從數據庫通過簡單查詢或各種組合關聯查詢得到一個關系表,而這部分SQL查詢根據各種數據庫產商長時間的優化(比如建立索引),已經非常成熟。數據集一般要通過FineReport報表模型的復雜處理才能生成最終的表樣。因此,從數據庫SQL查詢取出數據量越少,FineReport報表模型需要做的復雜處理和計算就越少,所花的時間和內存就少,從而可以提高性能。
2.1 SQL語句取具體的字段
我們一般會用select * from 這樣的形式將一個數據庫表中所有的字段都取出來,而其中一些字段是報表中不需要用到的,例如報表中只需要用到三個字段,但是數據庫中實際的表有十個字段,一些初學者習慣性的用select * from table1,這樣相當于把十個字段的數據都取到報表服務器端,增加了報表服務器端的內存占用以及減慢了運算速度,所以SQL語句中盡量不要用“*”號,而是寫上具體的字段,能夠減少報表服務器端的內存占用,加快報表的運算速度。
2.2 SQL中直接分組代替報表中分組
一些匯總類型的報表,例如制作一張訂單總額的表,可能會從訂單明細表中取出大量的數據記錄,然后進行數據匯總,即進行分組聚集運算,報表計算過程中我們可以在SQL中提前進行一次分組聚集,能夠大大減少取到的報表服務器的記錄數,加快取數和報表運算的速度。
SQL語句:SELECT 成本價,類別ID FROM 產品
從數據庫中選擇如上兩個字段,然后根據類別ID進行成本價的匯總,此時數據庫返回給報表處理的數據就有77條。如下:

優化的SQL語句:SELECT sum(成本價),類別ID FROM 產品 group by 類別ID
經過SQL優化后,報表需要處理的數據就只剩8條了。如下:

優化分析:
第一種做法,不僅僅取到報表服務器上記錄數多了,取數速度慢,而且報表模型需要對表數據列進行分組運算,增加了報表運行時間;
第二種做法,數據庫雖然要進行分組運算,但是數據庫中有索引,運算速度快,且取到報表服務器端的記錄數大大減少,取數速度大大加快,因此在報表模型進行分組運算的時候只要對很少的記錄數進行,報表的運算速度大大加快了。
實驗結果以及分析表明,第二種做法的性能遠優于第一種。所以,分組應該盡量在sql里進行。
2.3 SQL中直接排序代替報表中排序
報表計算過程中很多時候需要對數據進行排序,雖然排序運算可以在報表端進行,不過我們還是建議在SQL中提前將數據排序,這是因為數據庫中索引功能,通常是C/C++語言(往往在效率上比Java好)寫的,會使得排序運算的速度很快。
2.4 SQL中直接過濾代替報表中過濾
報表計算過程中很多時候并不需要對表中的所有記錄進行操作,而只是需要對部分滿足條件的記錄進行操作,雖然可以在報表設計器中對數據過濾,不過我們建議在SQL中對數據提前過濾,這樣數據庫返回的數據就減少了,既加快了取數速度,也加快了報表的運算速度。
3. 使用視圖、存儲過程
視圖是由SELECT語句組成的查詢定義的虛擬表,由一張或多張數據庫實際的表中的數據組成的,從數據庫系統外部來看,視圖就如同一張表一樣。
存儲過程通過流控制與SQL語句,可以對數據進行強大的運算與處理,對于業務比較復雜的應用,常常需要將原始數據通過存儲過程處理后再供報表使用。另外存儲過程運行前,數據庫會對其進行語法和句法的分析,并進行優化,這種已經編譯好的存儲過程極大地改善SQL語句的性能。在報表端也只需要書寫較短的調用語句來獲得結果,從而降低網絡的通信量。
所以表與表的連接、復雜的SQL盡量在數據庫中使用視圖或者存儲過程直接進行,這樣將復雜的SQL語句直接保存于數據庫服務器端(數據庫本身會對SQL語句進行語法分析并進行優化),在報表設計器端就不需要寫大段的SQL語句而是直接調用視圖或存儲過程了,一方面減少網絡傳輸量,減輕數據庫的壓力,另一方面加快了報表的運算速度。