技巧-代码查询优化

批量查询小技巧

Posted by Kang on September 9, 2019

技巧

业务需要单条获取

  一般来说,在没有前台页面的情况下,会将数据全部查询出来,这样就可能导致单次查询的数据量过大,查询耗时,所以需要对查询进行优化,可以使用引入分页和本地缓存的方式来优化整个查询,具体示例代码:
ExampleRecordDBTableReader
  特别需要注意的是,在使用的时候,ExampleRecordDBTableReader需要为有状态的,所以必须为非单利模式

大数据捞取

思路:将最大值与最小值之间的数据量划分为固定的块,每次将该块中符合条件数据捞取出来。

  1. loadContext全局变量,在for循环中保存查询全局变化参数。外部根据DataLoadResult中的 hasMore去控制是否需要捞数据
  2. 捞取sql示例
    1
    2
    3
    4
    5
    
    select from TableName
      where transaction_date=#transactionDate#
      and id >= #idStart# and id < #idEnd#
      order by id desc
      limit #pageStart#, #pageSize#
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    
     protected DataLoadResult<T> queryDataById(DataLoadContext loadContext) {
         LoggerUtil.info(logger, "按minId, maxId方式捞取数据, taskKey={0},taskBizId={1}",
             loadContext.getTaskKey(), loadContext.getTask().getBizId());
    
         initContextForId(loadContext);
         // 分页查询逻辑
         int pageSize = loadContext.getPageSize();
         long minId = Long.valueOf(loadContext.getBizData(TaskParamEnum.MIN_ID.getName()));
         long pageCount = Long
             .valueOf(loadContext.getBizData(TaskParamEnum.PAGE_COUNT.getName()));
         long count = Long.valueOf(loadContext.getBizData(TaskParamEnum.ID_COUNTER.getName()));
         if (count < pageCount) {
             // 总页数进行分页,由于通过id进行主键索引进行500行捞去。
             List<R> exportRecordList = loadExportRecordsById(loadContext.tableNo(),
                 loadContext.getBizDate(), 0, pageSize, count * pageSize + minId, count * pageSize
                                                                                  + minId + pageSize);
             updateContextForId(loadContext);
             List<T> dataMapList = assembleResult(exportRecordList);
             return new DataLoadResult(true,dataMapList);
         }
         return new DataLoadResult(false,null);
     }
    
     /**
      * 初始化根据id 捞取上下文
      * @param loadContext
      */
     protected void initContextForId(DataLoadContext loadContext) {
         //ID_COUNTER标识当前第几页
         if (loadContext.getBizData(TaskParamEnum.ID_COUNTER.getName()) == null) {
             loadContext.putBizData(TaskParamEnum.ID_COUNTER.getName(), "0");
             // 分页查询逻辑
             long maxId = getMaxId(loadContext.tableNo(), loadContext.getBizDate());
             long minId = getMinId(loadContext.tableNo(), loadContext.getBizDate());
             long totalCount = maxId - minId + 1;
             int pageSize = loadContext.getPageSize();
             // 只有一页的场景
             long pageCount = (totalCount + pageSize - 1) / pageSize;
             loadContext.putBizData(TaskParamEnum.MIN_ID.getName(), String.valueOf(minId));
             loadContext.putBizData(TaskParamEnum.PAGE_COUNT.getName(),
                 String.valueOf(pageCount));
         }
     }
        
     protected void updateContextForId(DataLoadContext loadContext) {
         loadContext.putBizData(TaskParamEnum.ID_COUNTER.getName(), String.valueOf(Long
             .valueOf(loadContext.getBizData(TaskParamEnum.ID_COUNTER.getName()) + 1L)));
     }