成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Excel百萬數據高性能導出方案!

大數據 數據倉庫
很多小伙伴門在開發數據導出功能時,習慣性使用Apache POI的HSSF/XSSF組件。這類方案在數據量超過5萬行時,會出現明顯的性能斷崖式下跌。根本原因在于內存對象模型的設計缺陷:每個Cell對象占用約1KB內存,百萬級數據直接導致JVM堆內存爆炸。

前言

在我們的日常工作中,經常會有Excel數據導出的需求。

但可能會遇到性能和內存的問題。

今天這篇文章跟大家一起聊聊Excel高性能導出的方案,希望對你會有所幫助。

1.傳統方案的問題

很多小伙伴門在開發數據導出功能時,習慣性使用Apache POI的HSSF/XSSF組件。

這類方案在數據量超過5萬行時,會出現明顯的性能斷崖式下跌。

根本原因在于內存對象模型的設計缺陷:每個Cell對象占用約1KB內存,百萬級數據直接導致JVM堆內存爆炸。

示例代碼(反面教材):

// 典型內存殺手寫法
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
for (int i = 0; i < 1000000; i++) {
    Row row = sheet.createRow(i); // 每行產生Row對象
    row.createCell(0).setCellValue("數據"+i); // 每個Cell獨立存儲
}

這種寫法會產生約100萬個Row對象和1000萬個Cell對象(假設每行10列),直接導致內存占用突破1GB。

更致命的是頻繁Full GC會導致系統卡頓甚至OOM崩潰。

2.流式處理架構設計

高性能導出的核心在于內存與磁盤的平衡。

這里給出兩種經過生產驗證的方案:

方案一:SXSSFWorkbook

使用SXSSFWorkbook類,它是Apache POI的增強版。

具體示例如下:

// 內存中只保留1000行窗口
SXSSFWorkbook workbook = new SXSSFWorkbook(1000); 
Sheet sheet = workbook.createSheet();
for (int i = 0; i < 1000000; i++) {
    Row row = sheet.createRow(i);
    // 寫入后立即刷新到臨時文件
    if(i % 1000 == 0) {
        ((SXSSFSheet)sheet).flushRows(1000); 
    }
}

通過設置滑動窗口機制,將已處理數據寫入磁盤臨時文件,內存中僅保留當前處理批次。實測百萬數據內存占用穩定在200MB以內。

方案二:EasyExcel

EasyExcel是阿里巴巴開源的Excel高性能處理框架,目前在業界使用比較多。

最近EasyExcel的作者又推出了FastExcel,它是EasyExcel的升級版。

// 極簡流式API示例
String fileName = "data.xlsx";
EasyExcel.write(fileName, DataModel.class)
    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
    .sheet("Sheet1")
    .doWrite(data -> {
        // 分頁查詢數據
        int page = 0;
        while (true) {
            List<DataModel> list = queryByPage(page, 5000);
            if (CollectionUtils.isEmpty(list)) break;
            data.write(list);
            page++;
        }
    });

該方案通過事件驅動模型對象復用池技術,百萬數據導出內存占用可控制在50MB以下。

其核心優勢在于:

  • 自動分批加載數據(默認每批次5000條)
  • 通過反射緩存消除重復對象創建
  • 內置樣式優化策略避免內存碎片

3.數據庫查詢的黃金法則

即便導出工具優化到位,若數據查詢環節存在瓶頸,整體性能仍會大打折扣。這里給出三個關鍵優化點:

3.1 解決深度分頁問題

傳統分頁查詢在百萬級數據時會出現性能雪崩:

SELECT * FROM table LIMIT 900000, 1000 -- 越往后越慢!

正確姿勢應使用游標方式:

// 基于自增ID的遞進查詢
Long lastId = 0L;
int pageSize = 5000;
do {
    List<Data> list = jdbcTemplate.query(
        "SELECT * FROM table WHERE id > ? ORDER BY id LIMIT ?",
        new BeanPropertyRowMapper<>(Data.class),
        lastId, pageSize);
    if(list.isEmpty()) break;
    lastId = list.get(list.size()-1).getId();
    // 處理數據...
} while (true);

該方案利用索引的有序性,將時間復雜度從O(N2)降為O(N)。

3.2 減少字段數量

-- 錯誤寫法:全字段查詢
SELECT * FROM big_table 

-- 正確姿勢:僅取必要字段
SELECT id,name,create_time FROM big_table

實測顯示,當單行數據從20個字段縮減到5個字段時,查詢耗時降低40%,網絡傳輸量減少70%。

3.3 連接池參數調優

# SpringBoot配置示例
spring:
  datasource:
    hikari:
      maximum-pool-size: 20 # 根據CPU核數調整
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

導出場景建議使用獨立連接池,避免影響主業務。

連接數計算公式:線程數 = CPU核心數 * 2 + 磁盤數。

4.生產級進階技巧

4.1  異步分片導出

想要提升Excel數據導出的性能,我們必須使用多線程異步導出的方案。

具體示例如下:

@Async("exportExecutor")
public CompletableFuture<String> asyncExport(ExportParam param) {
    // 1. 計算分片數量
    int total = dataService.count(param);
    int shardSize = total / 100000; 

    // 2. 并行處理分片
    List<CompletableFuture<Void>> futures = new ArrayList<>();
    for (int i = 0; i < shardSize; i++) {
        int finalI = i;
        futures.add(CompletableFuture.runAsync(() -> {
            exportShard(param, finalI * 100000, 100000);
        }, forkJoinPool.commonPool()));
    }

    // 3. 合并文件
    CompletableFuture.allOf(futures.toArray(new CompletableFuture)
        .thenApply(v -> mergeFiles(shardSize));
    return CompletableFuture.completedFuture(taskId);
}

通過分治策略將任務拆解為多個子任務并行執行,結合線程池管理實現資源可控。

4.2 配置JVM參數

我們需要配置JVM參數,并且需要對這些參數進行調優:

// JVM啟動參數示例
-Xmx4g -Xms4g 
-XX:+UseG1GC 
-XX:MaxGCPauseMillis=200
-XX:ParallelGCThreads=4
-XX:Cnotallow=2
-XX:InitiatingHeapOccupancyPercent=35

這樣可以有效的提升性能。

導出場景需特別注意:

  • 年輕代與老年代比例建議2:1
  • 避免創建超過50KB的大對象
  • 使用對象池復用DTO實例

4.3 整體方案

Excel高性能導出的方案如下圖所示:

圖片圖片

用戶點擊導出按鈕,會寫入DB,生成一個唯一的任務ID,任務狀態為待執行。

然后后臺異步處理,可以分頁將數據寫入到Excel中(這個過程可以使用多線程實現)。

將Excel文件存儲到云存儲中。

然后更新任務狀態為以完成。

最后通過WebSocket通知用戶導出結果。

5.總結

經過多個千萬級項目的錘煉,我們總結出Excel高性能導出的黃金公式:

高性能 = 流式處理引擎 + 分頁查詢優化 + 資源管控

具體實施時可參考以下決策樹:

圖片

最后給小伙伴們的三個忠告:

  • 切忌過早優化:在需求明確前不要盲目選擇復雜方案
  • 監控先行:務必埋點記錄導出耗時、內存波動等關鍵指標
  • 兜底策略:始終提供CSV導出選項作為保底方案

希望本文能幫助大家在數據導出的戰場上,真正實現"百萬數據,彈指之間"!

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2025-05-06 01:00:00

Excel高性能內存

2023-02-03 08:21:30

excelMySQL

2025-04-02 08:21:10

2023-02-25 10:04:21

JavaExcel導出功能

2019-03-01 11:03:22

Lustre高性能計算

2017-11-28 17:14:16

華為云

2020-03-23 14:35:28

前端架構應用程序

2019-12-31 10:33:57

Netty高性能內存

2025-03-03 10:30:00

JavaExcelSpringBoot

2009-07-31 11:41:12

光纖連接數據中心

2010-03-12 08:33:55

Greenplum數據引擎數據倉庫

2012-11-23 10:00:55

SQL性能測試

2013-09-22 12:48:59

2021-01-29 18:30:27

戴爾

2009-04-03 11:26:12

AMD上海皓龍

2022-11-24 10:55:32

2024-09-12 17:23:02

2014-03-06 09:57:49

西部數據高性能雙盤位

2011-04-20 14:28:38

SQL優化
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲成网 | 福利国产| 色在线免费视频 | 中文字幕国产精品视频 | 超碰天天 | 亚洲欧美成人影院 | 日韩在线中文字幕 | 麻豆一区一区三区四区 | 久久国产麻豆 | 日韩三级免费观看 | 青青草视频网站 | 亚洲第一成人av | 91中文字幕在线 | 四虎最新地址 | 亚洲国产日韩欧美 | 日日碰狠狠躁久久躁婷婷 | 国产欧美精品一区二区三区 | 干干干操操操 | 欧美午夜精品 | www久久av | 华丽的挑战在线观看 | 久久久久久久国产 | 黄色网址大全在线观看 | av黄色片在线观看 | 欧美高清性xxxxhdvideosex | 在线播放中文字幕 | 亚洲另类视频 | 青青久在线视频 | 日韩三级| www.玖玖玖 | 在线免费观看成年人视频 | 在线中文字幕亚洲 | 粉嫩一区二区三区国产精品 | 日本免费一区二区三区 | 久久午夜精品福利一区二区 | 成人精品一区二区 | 91五月天| 韩国av一区二区 | 中文字幕在线网 | 欧美精品一区二区三区四区五区 | 国产一区在线免费观看 |