大数据下(多字段排序或unique_key)高性能分页含过滤条件

1.通过where 条件后,量不大可以 limit index,size.

 

2. 量大,索引+orderby法 本质上 要有个unique_key.

order by  的key, 必须要有索引,性能好.

where unique_key > #{index} order by unique_key 

nextIndex = index + 最后一个+1; (这个对多字段 unique_key是难点 )

2.1 unique_key 一个字段,基本上是id然后必要的时候,你需要对应的索引用于where筛选. 

2.2 unique_key 多个字段.(难点)

  2.2.1 筛选度高的放前面. (一般选id)

  2.2.2 id放前面,并且把筛选条件放到同一个索引了. ( 筛选低的放前面 ? 待试验. 可以先= ,最好一个 > .)

  A场景: 如果是查询条件是> ,相当于会有两个字段都是> 或者 < . 是否能有效利用到 联合索引? 最好另外一个改成 in( ) .

 nextIndex =  最后一个的 多个元素, 然后统一  字段1 > indexA and 字段2 > indexB .

 核心抓住: 回传所有的keyCursor.(整体有序不代表, 不等各个字段分拆后 字段1 > indexA and 字段2 > indexB 有序

而是  if( fist > indexA,1, if (fist < indexA,-1,if(second > indexB ,1,if(second= indexB ,1))) = 1 ,代表大于这个unique.

 

 

   

unique_key: id

比如 idx_id_start_time.

这样你就可以写分页的sql了.

2.2 unique_key 多个字段.

 2.2.1 查询条件里有这几个字段

 2.2.2 查询条件里没这几个字段.

 

示例:

  含筛选条件的多分组分页小数据量查询. 

    两个size, fetchSizeForClient : 用户期望获取的size.sizeForDb 向 db中查询的次数.

   场景1: 如果前端设置fetchSizeForClient=1,sizeForDb=50 可能会导致多查49条数据. 

    场景2: 如果filter条件很多, sizeForDb太小就会导致db查询多次, 导致性能比较差. sizeForDb不能太大,也不能太小.

      


    /** 
     * sql示例: select * from table order by name,id limit #{},#{}
     *
     * @param searchBatchFunction search回调接口,可以硬写死
     * @param fetchSizeForClient
     * @param pageItemFilter filter回调接口,可以硬写死
     * @param <T>
     * @return
     * @throws ServiceException
     */

    private <T> PageVO<List<T>> fetchRoomPageListsFromDBWithFilter(SearchBatchFunction searchBatchFunction, Integer fetchSizeForClient,PageItemFilter pageItemFilter) throws ServiceException {
        PageVO<List<MeetingRoomVo>> pageVo = new PageVO<>();
        // 兜底初始化.
        pageVo.setHasMore(false);
        pageVo.setResult(Lists.<MeetingRoomVo>newArrayList());


        List<MeetingRoomVo> result = Lists.newArrayList();
        Long index = indexInput;

        // 未获取满,继续. 内有break
        while (result.size() < fetchSizeForClient) {

            // 如果是获取所有,那就所有会议室挨个获取.
            Integer sizeForDb = diamond.getIntDefault("PageSizeForDB", 50);

            List<T> items = searchBatchFunction.execute(index, sizeForDb);

            if (CollectionUtils.isEmpty(items)) {
                break;
            }
            List<T> initialItems = Lists.newArrayList(items);

            // items传入后可能会被删除元素.
            T indexItem = pageItemFilter.filter( result, items);

            if (indexItem == null) {
                logger.debug("calacIndex_indexItemMayBeNull_null ,index={},add={}", index, initialItems.size());

                index = index + initialItems.size();

            } else {
                // index就是序号,原因: 当前模式是 limit #{index},#{size},
                Integer count = 0;
                for (T item : initialItems) {
                    count++;
                    if (indexItem.getId().equals(item.getId())) {
                        break;
                    }
                }
                logger.debug("calacIndex_indexItemVOMayBeNull_notNull ,index={},add={},{}", index, count, JSON.toJSONString(indexItem));
                index = index + count;
            }
        }

        pageVo.setNextCursor(index);
        pageVo.setResult(result);

        if (fetchSizeForClient <= result.size()) {
            pageVo.setHasMore(true);
        } else {
            pageVo.setHasMore(false);
        }

        return pageVo;
    }

   含筛选条件的多分组分页大数据量查询.  (只需要将上面的加个where 条件,并且index改用)

附录:MySQL大数据量分页查询方法及其优化

 

大数据分页实现与性能优化 

https://www.cnblogs.com/wlandwl/p/paginaction.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值