FacebookTwitterLineHatena

「報表太慢了吧,我就按門店查詢下這個月的銷售,卡了1分鐘了還沒出來,你們做這個到底行不行?」

拖慢報表速度的5個坑,你中了幾個?

在老闆要、業務改、指標混亂、口徑不統一的狀況下好不容易上線了一張報表,就被埋怨報表出數太慢,整天要求提速提速。這一度成為表哥表姐們的心頭大患。解決這個問題除了選擇性能比較好的報表軟體外,在製作報表中也可以通過一些方法優化報表速度。

下面這篇文章來自帆軟論壇番薯 shinger@126.com,他總結了在使用finereport報表BI商業智慧軟體時,製作的報表展示速度慢的5個原因,以及如何進行優化。看看你有沒有中招吧!

1.為圖方便寫程式碼,寫SQL的時候,直接在有索引的欄上直接用函數

舉個例子:
銷售單上銷售日期這個欄上鍵有所有,要根據年和月2個參數來查詢某個月的銷售單數據,很多就是這樣寫的:以MS-SQL為例

select * from 銷售單 where year(銷售日期)=${年份} and month(銷售日期)=${月份}

其實這樣會導致索引失效,如果銷售單這個表上的數據比較多,那麼執行就會非常慢

正確的寫法:
改變思路,在參數上執行計算,比方說查詢2017年10月份的,轉換成 [銷售日期>=’2017-10-01′ and 銷售日期<'2017-11-01'] 這種形式

select * from 銷售單 where 銷售日期 >= DATEADD(MONTH,${月份}-1,DATEADD(YEAR,${年份}-1900,'1900-01-01')) and 銷售日期

當然,關於用年月來計算日期,還有其他方法,這裡不一一列舉

2.數據集返回結果浪費,未遵循用多少取多少的原則。

設計數據集的時候,並不是遵循用多少數據取多少數據的原則,而是先把數據都拉過來,然後在設計器中設定條件過濾來獲取想要的數據,我們應該檢查數據集的結果是否有浪費的現象。數據集返回的結果,應該全部都能用在報表裡面,盡量不要有冗餘,其實這個問題,很多熟悉SQL的都會有意無意的這樣做,比方說為了避免在儲存過程中寫過多的IF邏輯判斷,然後取了一大堆的數據到臨時表,然後根據某個參數的值把不符合條件的數據delete掉。

3.SQL未學習透徹,寫的複雜低效。

設計數據集時,因為不太懂SQL,寫了邏輯複雜、可讀性差並且效率低下的SQL腳本,這個問題需要我們去好好學習一下SQL了!
推薦sql學習的文章:零基礎快速自學SQL,1天足矣!

4.數據集返回的數據,應該先根據報表需要統計的粒度進行聚合運算,而不是直接返回原始數據,然後在報表裡面去匯總。

仍然以銷售單為例,比方說銷售單一個月有50萬條單據,某個報表要按地區進行統計。

錯誤的做法:
select * from 銷售單 where 銷售日期 >= '2017-10-01' and 銷售日期 < '2017-11-01'
--返回50萬條記錄

正確的做法:
select 地區,sum(銷售金額) as 銷售金額 from 銷售單 where 銷售日期 >= '2017-10-01' and 銷售日期 < '2017-11-01' group by 地區
--有多少個門店返回多少條記錄

這樣能減少數據從資料庫返回到報表伺服器的I/O開銷

5.在報表數據多的時候,做SQL注入查詢。

仍然以銷售單為例,比方說銷售單上有客戶ID,沒有客戶地址,客戶地址存在客戶資料表上,我們需要做一個銷售單明細報表,上面要有客戶地址,有的人會這樣寫來獲取客戶地址:

在儲存格中設定公式
=sql("銷售數據","select 客戶地址 from 客戶信息 where 客戶ID = '"+B3+"'",1,1)

這樣的做法會導致B3儲存格擴展多少次,這個SQL腳本就會執行多少次,之前我有個報表用類似的方法來寫,導致一個返回幾千條數據的報表,執行了10幾分鐘還沒執行完。

正確的做法是:
盡量在SQL中進行關聯,而不是在FineReport報表設計器中用條件過濾或者公式去關聯取數。

你有更多加快報表速度的妙招,或是對作者寫的這些內容有疑惑,歡迎來帆軟論壇聊一聊!

原文鏈接:http://bbs.fanruan.com/forum.php?mod=viewthread&tid=107038&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline

喜歡這篇文章嗎?歡迎分享按讚,給予我們支持和鼓勵!

熱門文章推薦

立即試用,可獲取更多 報表範本和案例

免費試用