100萬行數據導出到Excel的優化方案

1》場景

  項目中需要從數據庫中導出100萬行數據,以excel形式下載並且只要一張sheet(打開這麼大文件有多慢另說,呵呵)。

  ps:xlsx最大容納1048576行 ,csv最大容納1048576行,xls最大容納65536行,但是存放相同的數據量 文件大小排序:xls>csv>xlsx ;xls是biff8的二進制文件,就是個B+樹而xlsx是 xml的zip壓縮文件。

2》常規做法

  按照平常的做法,先到數據庫中取數然後循環組裝成一個list,然後用excel工具(我用的是POI)生成excel。

3》遇到的問題

  1' 內存經常溢出。

  2' 組裝list,生成excel慢,50萬的數據花了一個小時都沒見完成。

4》解決方法

  1' POI 改用 SXSSFWorkbook 參看 比如SXSSFWorkbook wb = new SXSSFWorkbook(100);在內存中只保留100行記錄,超過100就將之前的存儲到磁盤裏,

      2' 調整JVM 相關的參數 -Xmx....

    3' 循環中減少使用new,儘量複用;String改爲StringBuffer就不說了,重點是在組裝一行數據時,一直比較喜歡用map來拼裝,但是在我功能上發現還是耗內存的,後來的GC時間太長,造成嚴重拖累組裝數據的效率,後來發現由HashMap改爲用StringBuffer拼接行數據效率直接就上去了,當然指定合理的StringBuffer的起始容量效率就更好了。

  ps:StringBuffer 的構造器會創建一個默認大小(通常是16)的字符數組。在使用中,如果超出這個大小,就會重新分配內存,創建一個更大的數組,並將原先的數組複製過來,再丟棄舊的數組。在大多數情況下,你可以在創建 StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高性能。

      4' 下載任務由同步改爲異步,用戶提交了後只要等待郵件通知即可,我用了quartz。

5》效果

    100萬數據組裝以及生成excel大概要10分鐘,平均下來1分鐘10萬條,我的小黑腰不酸腿不疼了。

好了就這些,我也看了,網上導出很多是分批導出或者用csv的解決的,但是我就這樣的需求,人家任性沒辦法,我的方法還有待完善的地方,歡迎交流。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章