效能最佳化之報表資料預先計算

xiaohuihui發表於2019-12-10

報表應用中,如果資料量較大或計算過程較複雜,往往會導致報表資料來源準備過慢,從而影響報表效能。這種情況下可以預先計算報表需要的資料,在呈現時直接引用,使得使用者在訪問報表時可以迅速地獲得響應。

一、當前的手段及弊端

由於報表在訪問時常常需要引數,因此顯然不可能把所有引數組合對應的報表資料來源都準備好,所以預先計算通常只生成中間資料,在呈現時仍然要再進行一些後續的簡單計算(如過濾、分組彙總、排序等)。不過即便如此,也不太可能完全由報表工具在中間資料基礎上完成所有後續運算,因此報表工具通常只能完成一些小資料量的運算。也就是說,儲存的中間資料還需要有有再次計算的能力,所以一般情況下會將中間資料以中間表的形式儲存在資料庫中,以便在呈現時再借用資料庫的計算能力。

採用中間表進行預先計算會存在以下弊端:首先,將過多的計算工作交給資料庫做,無疑會加大資料庫的壓力,甚至反而造成效能不升反降;其次,中間表太多容易導致管理混亂,由於資料庫採用非層次結構(與檔案系統的樹形結構不同),因此大量存在的中間表往往會增加資料庫管理難度。此外,從資料庫中讀取較大的中間表還會出現 I/O 瓶頸,同樣會導致報表效能不佳。

二、潤乾報表的解決方案

潤乾報表的預先計算方案(結合集算器實現)不需要使用資料庫中間表,從而可以避免上述弊端。潤乾報表內建的運算引擎擁有完整的計算能力,一方面可以將中間資料存放在檔案中,另一方面還可以對檔案進行再計算後作為報表資料來源,縮短報表計算時間,提升報表效能。

這種方式看上去和使用資料庫中間表類似,都需要事先計算準備資料,但也有很大的不同:第一,不會佔用昂貴的資料庫空間,不會增加資料庫負擔;第二,中間資料的組織管理基於檔案系統,清晰明瞭;第三,資料量大時不會出現 IO 瓶頸。

潤乾報表能夠做到這些,得益於內建了專門用於資料計算的集算引擎。集算引擎與檔案系統可實現無縫互動(讀入和輸出),可以讀取多種檔案格式,如常見的文字、Excel 等,也包括效率更高的二進位制檔案,從而使檔案具備再計算的能力,輕鬆實現報表預先計算。

下面用一個例子說明潤乾報表進行預先計算的步驟:

1、將需要的中間結果儲存成檔案

潤乾報表支援常見的文字檔案格式,例如可以將訂單明細分組彙總後的資料直接存放在文字(orderDetail.txt)中。如果希望提高效能,潤乾報表還支援更高效的二進位制檔案格式,比文字能快出 2-5 倍,在集算器中執行如下程式碼就能將文字檔案轉換成二進位制格式檔案。

file(“E:/ 訂單明細.b”).export@b(file(“E:/ 訂單明細.txt”.cursor())

當然,生成中間資料的過程本身也可以採用集算器實現,但非本文關注點,此處不再詳述。

2、 基於中間資料檔案生成報表源

潤乾報表可以直接基於檔案進行再次計算,從而獲得報表資料來源,比如下面的過濾演算法。

指令碼中使用的引數及其含義如下:

imagepng

其中 cols 為選出列名,where 為過濾條件(引數傳遞時拼接成上述格式),num 為取出的記錄數。

指令碼內容:

A
1 =file(“E:/ 最近 5 年訂單初步彙總.txt”).cursor@t(${cols})
2 =A1.select(${where})
3 =A2.fetch(num)
4 return A3

上述指令碼基於檔案進行過濾和分組彙總操作,其中:

A1:透過檔案遊標(流式處理)讀入大文字資料,此處支援選擇列,使用者可以根據引數控制選出的資料列。

A2:按照引數進行條件過濾,結果仍然是遊標。

A3:按照引數限制記錄數,取出遊標中的記錄。

A4:為報表返回結果集。

上述指令碼只處理了一箇中間檔案,如果需要從多個檔案同時查詢資料,指令碼可以這樣編寫(以 2 個為例):

A
1 =file(“E:/1996-1999 年訂單初步彙總.txt”).cursor@t(${cols})
2 =file(“E:/2000-2005 年訂單初步彙總.txt”).cursor@t(${cols})
3 =[A1,A2].conj@x()
4 =A3.select(${where})
5 =A4.fetch(5000)
6 return A5

其中中間資料檔案按年份儲存,每 5 年一個。如果查詢 1996 到 2005 年間的資料,就需要讀取 2 個檔案。指令碼中 A3 對兩個檔案的遊標進行了縱向拼接,合併成一個遊標,然後採用與第一個指令碼相同的方式進行處理。當查詢的資料範圍繼續擴大,需要多個檔案的時候,可以透過迴圈的方式將多個檔案遊標進行縱向拼接合並。

3、設計報表

這一步包括在潤乾報表中呼叫集算指令碼,編輯報表表示式完成報表製作等等,這些是報表製作的常規動作了,不再贅述。

與一般最佳化方式類似,使用預先計算來提高報表效能要充分考慮使用場景。對某些計算過程容易拆分的場景特別適合使用預先計算,如大表彙總資料與其他表做連線,這時可以先將大表彙總資料預先存成檔案,再與其他表做連線計算。此外,資料的實時性要求也需要充分考慮,比如在歷史查詢類的報表中就比較適合使用預先計算,當然潤乾報表還提供了其他手段來保證資料的實時性要求。

總結一下,由於一般報表工具不具備檔案計算能力,因此要實現預先計算往往要藉助資料庫進行;而潤乾報表擁有完整的檔案計算能力,可以避免資料庫中間錶帶來的各種弊端,這一點對使用者極具實用價值。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900830/viewspace-2667673/,如需轉載,請註明出處,否則將追究法律責任。

相關文章