百萬級分組大報表開發與呈現

2021-09-20 01:23:02 字數 3386 閱讀 1364

在《秒級展現的百萬級大清單報表怎麼做》中,我們介紹了無論 rdb 還是非 rdb,潤幹報表都能夠通過非同步執行緒實現秒級海量大清單報表(以下簡稱:大報表)。實際業務中,除了查詢明細,有時還要展現全量彙總資料,或者查詢分組明細和計算分組彙總。本文就將介紹這些帶有彙總和分組的大報表的開發方法。

帶彙總的大報表

在大報表中計算彙總值與常規報表基於報表內資料進行的彙總不同,大報表由於採用非同步執行緒,因此無法通過報表內資料進行彙總(因為每次只能取到部分資料),只能在資料處理階段計算彙總值並交給報表呈現。

我們還是使用《秒級展現的百萬級大清單報表怎麼做》中 sql 源大報表的例子,現在需要在每頁最後一行顯示訂單彙總情況(訂單數量、訂單總額、運費總額)。

製作報表模板

增加乙個資料集 ds2 計算彙總值:

報表中最後一行引入 ds2 彙總值進行呈現,這裡為了每頁都包含彙總資料,設定最後一行屬性為報表尾。

當然,帶有彙總的大報表效能跟計算彙總值的 sql 執行效率強相關,所以可能會發現帶有彙總的大報表要比單純查詢明細慢一些。

分組大報表

實際業務中,簡單呈現大報表清單往往還不夠,有時還需要對海量資料進行分組,呈現彙總及明細情況。下面,我們就以訂單資料為例,查詢一下按地區分組的明細及訂單金額彙總。

需求分析

首先,需要呈現分組明細的報表無法在資料來源端進行聚合,例如通過 sql 聚合後就不包含分組明細了,除非再查詢一次進行拼接,但查詢兩次顯然會嚴重影響效能。因此我們需要盡量將明細資料讀出後在應用端進行分組聚合。

那問題就來了,由於海量資料要通過分批讀取的方法進行呈現,如何保證讀取的每批分組資料是完整的?如果分組資料不完整,分組聚合的結果顯然也就不正確了。因此,除了要保證能在應用端實現聚合,還要保證批量讀取資料時分組資料的完整性。

下面就是潤幹報表結合集算器(資料集)實現分組大報表的過程。

報表資料準備

我們需要編寫集算器 spl 指令碼進行資料準備。這裡,我們要編寫兩個 spl 指令碼,分別實現:查詢分組明細並計算彙總,以及通過游標分批為報表返回結果集。

spl 指令碼 1:group-detail.dfx

設定指令碼引數:

編寫 spl 指令碼:

spl 解析:

1、 a2 查詢資料庫,sql 中指定按照分組字段(貨主地區)排序,以便後續可以每次取出整個分組進行彙總。為此需要在排序欄位上建立索引,避免全表排序時間過長。

2、 a3 迴圈游標,以貨主地區為標記,保證每次讀取的記錄數為乙個地區資料

3、 b4 增加標誌位,用於後續報表展現中突出彙總行。標誌為 0 時表示是明細記錄

4、 b5 針對每個分組進行彙總

5、 b6 將分組值追加到明細記錄中,標誌設為 1,表示是彙總記錄

6、 b7 返回分組明細和彙總集合。注意這裡 return 寫在迴圈內,因此會多次返回分組集合

關於 for cs,n;x 用法

在集算器 spl 指令碼中,for cs,n;x 表示針對游標 cs 通過迴圈遍歷資料,每輪從游標讀取 n 條記錄或者直到記錄中的 x 發生變化,迴圈全部結束後關閉游標。大資料量的分組取數是這種迴圈的常用之處。如果省略了 n 和 x,那就簡單地返回游標中所有資料並關閉游標。函式的具體說明可以參考:

當大資料集按照分組字段有序時,這種取數方式每次可以讀取乙個完整分組到記憶體中參與計算,不過這時仍然要求分組不能很大(記憶體能裝下)。而在金融和電信行業中,經常要基於單使用者做資料分析,也就是按使用者分組,而每個使用者的流水記錄規模又較大,常規的拆分方法作起來十分複雜。而通過集算器就可以很好地解決這類問題了。

spl 指令碼 2:main.dfx

設定指令碼引數:

編寫 spl 指令碼:

前乙個 spl 指令碼 group-detail.dfx 解決了分組查詢明細並彙總計算的問題。這個指令碼 main.dfx 則可以分批次取數並提供給潤幹報表,從而實現非同步大報表呈現。指令碼中 a1 通過 cursor 函式直接呼叫前一指令碼生成游標,由 a2 將游標返回給報表。

關於 cursor() 函式

使用 cursor 函式呼叫 spl 指令碼生成游標時,被呼叫的 spl 指令碼可以有多個返回結果集(例如在 for 迴圈中的多個 return),而游標取數(fetch)時可以依次使用多個 return 結果,無需等待所有結果集都準備好再使用,原理如下圖所示。函式的具體說明可以參考:

結合大報表使用 cursor() 函式執行原理

設計報表模板

設定報表引數,查詢起止日期:

設定資料集引用 main.dfx 並傳遞日期引數:

按照大報表模板設計思路,編寫表示式

為了將彙總行高亮顯示出來,這裡利用了資料準備階段增加的標誌位 flag 列,當 flag 值為 1 的時候代表該行為彙總行,設定背景色表示式:if(a3==1,-3355444)

設定大資料集

發布到 web

將做好的模板發布到 web 端,效果如下:

當然,標誌位 flag 列也可以設定為隱藏。

效果調整

調整報表模板,將標誌位 flag 列隱藏,並設定 b3 格的擴充套件屬性 同值合併為「縱向合併」

展現時分組列則帶有合併格的效果:

注意事項

在《秒級展現的百萬級大清單報表怎麼做》中,我們提示了大報表不要全表排序,也不適合高併發場景。除此以外,對於帶有分組彙總和明細的大報表還應該注意:

單個分組不宜過大

由於計算分組明細和彙總值時需要將某乙個分組資料全部載入到記憶體中進行計算,因此分組相對記憶體容量不宜過大,從而確保單個分組資料能進行全記憶體計算。

報表工具選型對比系列 大報表

有些報表查詢出的資料行數可達千萬甚至上億,這類報表通常被叫做大報表,大多數情況下都是些清單明細資料包表,也有少量分組報表。針對大報表,如果像常規報表一樣,將資料一次性全取再交給前端呈現是不可行的。一是等待時間太長,使用者體驗差 二是很可能導致記憶體溢位造成應用崩潰。首先了解下各家的解決方式或機制。帆...

報表工具選型對比系列 大報表

有些報表查詢出的資料行數可達千萬甚至上億,這類報表通常被叫做大報表,大多數情況下都是些清單明細資料包表,也有少量分組報表。針對大報表,如果像常規報表一樣,將資料一次性全取再交給前端呈現是不可行的。一是等待時間太長,使用者體驗差 二是很可能導致記憶體溢位造成應用崩潰。首先了解下各家的解決方式或機制。帆...

報表工具選型對比系列 大報表

有些報表查詢出的資料行數可達千萬甚至上億,這類報表通常被叫做大報表,大多數情況下都是些清單明細資料包表,也有少量分組報表。針對大報表,如果像常規報表一樣,將資料一次性全取再交給前端呈現是不可行的。一是等待時間太長,使用者體驗差 二是很可能導致記憶體溢位造成應用崩潰。首先了解下各家的解決方式或機制。帆...