You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JqGrid大数据集加载性能优化咨询(Java Spring MVC + Intramart环境)

JqGrid大数据集加载性能优化咨询(Java Spring MVC + Intramart环境)

我看了你的问题和代码,现在加载几千条数据要2分钟确实太影响用户体验了,核心问题应该是你当前用的是前端假分页——不管用户看第几页,后端都一次性把所有符合条件的数据查出来、处理完再传给前端,大数据量下数据传输、内存占用、前端渲染都会慢到爆炸。下面给你几个针对性的优化方案,都是结合你的代码和使用环境来的:

1. 先搞真正的服务器端分页(最关键!)

你现在的Repository方法是一次性查出所有数据,哪怕前端有分页控件,也只是把全量数据拿到前端后再切分,这在数据量大的时候完全行不通。得改成后端只返回当前页需要的数据:

  • 修改Repository方法:新增分页参数pageNum(当前页码)和pageSize(每页条数),SQL里加上数据库对应的分页语法(比如MySQL用LIMIT offset, pageSize,Oracle用ROWNUM),同时还要查询符合条件的总记录数,这样前端jqGrid才能知道总页数、总条数。
    比如你的SQL最后可以这么加:
    int offset = (pageNum - 1) * pageSize;
    sql += " LIMIT ?, ?";
    parameters.add(offset);
    parameters.add(pageSize);
    
    还要单独写一个统计总记录数的SQL(WHERE条件要和数据查询的完全一致),最后把总条数、当前页数据、总页数一起返回给前端,比如用Map封装成{ "total": 总页数, "page": 当前页, "records": 总条数, "rows": 当前页数据 }的结构。
  • 前端配置调整:确保你用的imui:listTable(基于jqGrid)开启服务器端分页,配置rowNum(默认每页条数)、rowList(可选条数),并且让它把分页参数(page、rows)传给后端。Intramart的imui组件应该有对应的属性配置,比如serverPaging="true"这类,你可以查下官方文档确认。

2. 优化数据库查询速度

数据库查询是性能瓶颈的重灾区,你的代码里有几个可以快速优化的点:

  • 别用SELECT *,只查需要的字段:你最后在Java层只用到了模型的部分字段,SQL里直接列出来这些字段,比如SELECT doc_type, plant_code, gr_doc, ... FROM v_gr_list_w_price_v2,减少视图返回的数据量,既省内存又省传输时间。
  • 给查询字段加索引:你的查询条件用到了tr_type、gr_date、gr_doc、vendor_code这些字段,如果有排序需求的话,排序字段也得加索引。先检查下v_gr_list_w_price_v2视图的底层表,这些字段有没有建索引,没有的话赶紧加,能大幅加快查询速度。
  • 把Java层的计算移到SQL里:你现在在循环里计算vat_rate、vat_amount这些值,能不能把vat_master的数据关联到查询中,直接在SQL里算出这些结果?这样就不用在Java层循环处理每条数据,能省很多时间。

3. 优化Java层的处理逻辑

你的Java代码里有几个拖慢速度的细节,调整后能明显提升效率:

  • 批量获取vat数据,别循环调用接口:你现在在循环里每次调用invoicingWorkflowService.getItem(maxDate),几千条数据就会调用几千次,这肯定慢死了!应该先把所有需要的maxDate收集起来,批量调用接口获取所有vat数据,然后存到一个Map里,循环的时候直接从Map里取,比如:
    // 先收集所有需要的maxDate
    Set<String> needMaxDates = new HashSet<>();
    for (InvoicingGRListModel model : sqlResults) {
        Integer grDate = Integer.parseInt(model.getGr_date());
        int maxDate = findMaxDate(validfromArray, grDate);
        needMaxDates.add(Integer.toString(maxDate));
    }
    // 批量获取vat数据
    Map<String, Item> vatItemMap = invoicingWorkflowService.getItemsByCodes(needMaxDates.toArray(new String[0]));
    // 循环时直接从map取数据
    Item item = vatItemMap.get(Integer.toString(maxDate));
    
  • 避免循环里重复创建对象:比如DecimalFormat可以提到循环外面,不用每次循环都新建;BigDecimal的计算尽量复用对象,减少内存开销。

4. 前端小优化

  • 确保jqGrid的loadonce设为false(默认就是),这样每次分页、排序、搜索都会请求服务器,只加载当前页数据。
  • 搜索功能保持在服务器端处理,别把全量数据拿到前端再过滤,你现在的前端点击按钮后再请求的逻辑是对的,继续保持。

按这些方法改完,加载速度应该能从分钟级降到秒级,甚至更快。

备注:内容来源于stack exchange,提问作者Lily

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 10:34:28