列表合计和排序优化

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

列表合计和排序优化

背景


有业务反馈列表开启了合计和排序功能时,在 IdQuery模式下会产生两个SQL,第一个SQL是将一些关键字段,合计字段以及排序字段作为查询字段,然后取TOP 10W数据进行查询,由于这些字段没有建索引导致扫描数据较多,性能较差。IdQuery查询模式的原理是先查出10W个ID,然后将10W个ID放在Redis,下次翻页时,可以直接根据缓存的10W个ID来获取当页ID并拼在Sql后面来加速当页数据的获取,之所以可以加速是因为翻页时从redis取到id的速度很快,同时Sql查询时可以使用id走索引来加快Sql查询。但是这种查询模式的问题在于之前取10W的ID时由于附带了合计,排序还有条数统计的功能,所以当数据量很大时会出现第一次加载很慢的情况。


优化方式


列表设计器增加开关“默认排序”复选框


“默认排序”关闭的时候(跟SqlQuery一样)

 1.直接返回一页数据

 2.第二次请求过来取条数,页数

 3.通过“合计”复选框来取汇总数据


 “默认排序”打开的时候

 1.取10W个id,带排序字段

 2.返回一页数据给前端,不处理合计数据,小于10W条直接返回条数

 3.大于10W条的情况下,前端再过来取条数

 4.通过“合计”复选框来取汇总数据


上面和目前IdQuery之前处理的区别在于

  第2条,小于10W条的情况下目前IdQuery会取合计数据

  第4条,大于10W条的情况下才通过“合计”复选框来取汇总数据


如果数据量比较大的情况下可以尝试将“默认排序”开关关闭,此模式基本和SqlQuery模式一样,但是有些地方需要注意。


SqlQuery模式需要改造点


目前列表使用的IdQuery查询模式,这种模式会先取10W个ID,然后再根据分页条数进行二次取数;如果有排序字段和汇总字段的情况,第一个取数sql还会带上排序字段和汇总字段进行查询,如果数据量比较大的情况下,第一个sql可能会产生性能瓶颈。还有一种查询方式是SqlQuery,SqlQuery的查询方式采用数据库的分页方式查询,只有一个sql,而且是取当页数据,列表的条数是串行取的,这种查询方式性能相对较好,平台目前想把查询方式默认改为SqlQuery;


但是如果有自定义取数的情况下,比如如下场景:


1. 用列表加载第三方数据,非数据库数据源

2. 在自定义取数逻辑,对数据集合进行加工,增加或减少数据

3. 在自定义取数逻辑,增加了额外的过滤条件

等。。。


因为,SqlQuery模式下,列表取条数,张数,以及合计数都是异步,或者需要用户点击进行取数,之前这些数据在IdQuery 下都是取数一次返回的,在getData 方法通过


getQueryResult().setDataCount(dataCount);

 getQueryResult().setBillDataCount(billDataCount);

 getQueryResult().setSummaryResults(summaryResults);

进行设置,但是SqlQuery模式下无法生效所以在SqlQuery模式下我们提供了三个方法进行重写,getRealCount,getBillDataCount,getSummaryResults,如果有以上或者类似场景需要业务进行重写


注意

这里如果取数时不是直接使用的getQueryBuilder().getFilters()查询,比如直接调用super处理,没有自己处理,这种情况下不需要重写getRealCount, getBillDataCount, getSummaryResults


示例:beforeCreateListDataProvider(自定义取数)


@Override
 public void beforeCreateListDataProvider(BeforeCreateListDataProviderArgs args) {
  System.err.println("beforeCreateListDataProvider");
  args.setListDataProvider(new ListDataProvider(){
@Override
   public int getRealCount() {
    // 获取真实条数
   }
   
   @Override
   public int getBillDataCount() {
    // 获取单据张数,只统计单据头的数量
   }
   
   @Override
   public List<SummaryResult> getSummaryResults() {
    // 获取合计字段值
   }
   @Override
   public DynamicObjectCollection getData(int start, int end) {
    int dataCount=selfQueryDataCount();
    int billDataCount=selfQueryBillDataCount();
    List<SummaryResult> summaryResults=selfQuerySummaryResult();
    
    // 自己的取数逻辑得到DynamicObjectCollection,
       // 这里如果取数时不是直接使用的getQueryBuilder().getFilters()查询,比如直接调用super处理,没有自己处理,这种情况下不需要重写getRealCount, getBillDataCount, getSummaryResults
    DynamicObjectCollection dynamicObjectCollection = selfQueryData(); 
    getQueryResult().setCollection(dynamicObjectCollection);
    getQueryResult().setDataCount(dataCount);
    getQueryResult().setBillDataCount(billDataCount);
    getQueryResult().setSummaryResults(summaryResults);
    
    return dynamicObjectCollection;
   }
   
  });
  super.beforeCreateListDataProvider(args);
 }


列表合计和排序优化

背景有业务反馈列表开启了合计和排序功能时,在 IdQuery模式下会产生两个SQL,第一个SQL是将一些关键字段,合计字段以及排序字段作为查询字...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息