批量循环查询

这篇具有很好参考价值的文章主要介绍了批量循环查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、rpc批量查询

    private List<DTO> query(String code, Integer type) {

        List<DTO> resultList = new ArrayList<>();
        List<DTO> skuList;
  
        //01.构造req
        Req request = buildTRequest(code, type);
        Response response;
        int fetchedCount = 0;
        int maxCycle = 1;
        boolean needMoreFetch = true;
        while (maxCycle <= 1000) {
            maxCycle++;
            try {
                response = skuGateway.query(request);
            } catch (Exception e) {
                throw new GatewayException(1,
                        String.format("获取sku失败 code:[%s]", code), e);
            }
            skuList = response.getData();
            
            if (CollectionUtils.isNotEmpty(skuList)) {
                resultList.addAll(skuList);
                fetchedCount += skuList.size();
            }

            if (total <= fetchedCount) {
                needMoreFetch = false;
            } else {
                request.setOffset(fetchedCount);
            }
        }
        return resultList;
    }

2、200、200条查询db数据

  • eg1
private void query(Request request) {

        int page = 1;
        List<DO> dOList = query(request, page);
        while (CollectionUtils.isNotEmpty(dOList) && page <= 1000) {//一次200,循环1000次,就是20w的数据量,肯定够了
            //处理数据
            judgeSameTask(dOList);
            if (200 > dOList.size()) {
                break;
            }
            page++;
            dOList = query(request, page);
        }
    }
  • eg2
private List<Info> batchQuery(Request request) {
        List<Info> result = new ArrayList<>();
        int page = 1;
        List<Info> infos = query(request, page);
        while (CollectionUtils.isNotEmpty(infos) && page <= 1000) {//一次200,循环1000次,就是20w的数据量,肯定够了
            result.addAll(infos);
            if (200 > infos.size()) {
                break;
            }
            page++;
            infos = query(request, page);
        }
        return totalSkuStockList;
    }


private List<ReturnPlanTaskDO> query(Request request, int page) {

        //01.构建查询条件
        XxxDOExample example = buildDOExample();

        //02.分页参数
        example.limit((page - 1) * 200, 200);

        //03.查询
        return myService.query(example);
    }
  • eg3
    private List<Info> batchQuery(TRequest request) {
        List<Info> result = new ArrayList<>();
        int page = 1;
        List<Info> infoList = query(request, page);
        while (CollectionUtils.isNotEmpty(infoList) && page <= 1000) {//一次200,循环1000次,就是20w的数据量,肯定够了
            result.addAll(infoList);
            if (200 > skuStockSaleInfos.size()) {
                break;
            }
            page++;
            infoList = query(request, page);
        }
        return result;
    }

    private List<Info> query(TRequest request, int page) {
        //01.构建查询条件
        Paging paging = new Paging();
        paging.setOffset((page - 1) * 200);
        paging.setLimit(200);
        request.setPaging(paging);

        //02.查询
        TResponse response = skuService.query(request);
        if (response != null && response.getCode() == 0) {
            return response.getInfoList();
        } else {
            return Collections.emptyList();
        }
    }
  • eg4
List<DO> result = Lists.newArrayList();
boolean loop = true;
long id = 0L;
do {
    XxxDOExample example = new XxxDOExample();
    example.limit(200);
    example.setOrderByClause("id asc");
    XxxDOExample.Criteria criteria = example.createCriteria();
    criteria1.andValidEqualTo(Boolean.TRUE);
    criteria1.andIdGreaterThan(id);
    List<DO> selectByExample = myMapper.selectByExample(example);
    if (CollectionUtils.isNotEmpty(selectByExample)) {
    result.addAll(selectByExample);
    int size = selectByExample.size();
    if (size < 200) {
        loop = false;
    } else {
        id = selectByExample.get(size - 1).getId();
    }
} while (loop);

第一次查询0-100,数据。(过滤或者处理一下这100条数据)后,存入list中,fetchCount = 100,

第二次查询100-200。(过滤或者处理一下这100条数据)后,存入list中,fetchCount = 200,

···

直到第10次处理完,fetchCount == total(1000)了,needFalse = false,停止查询

补充:为什么采用这种,每次查询100条,(处理或不处理)存入list,直到全部1000条都(处理或不处理)存入list。而不是直接一次查询出这1000条数据

解:因为如果你不查询一次,你根本就不知道数据库中有1000条满足条件的数据。所以,你也可以先查询一次limit offset(0-1)查出total = 1000,此时你再执行sql查询page(0-1000)一次全部查出来放入list

limit 20000 , 10:从第20001行数据开始查找,查找10条(20001、20002、····200010)=》 where id 〉 20000 limit 0 ,10。PageModel即父类RowBounds(mysql中的)即这种形式limit、offset

limit 10 offset 3 :(从第4行开始查找,找10条数据),即4、5、6、···13。

<if test="rows != null">
      <if test="offset != null">
        limit ${offset}, ${rows}    偏移量、多少条
      </if>
      <if test="offset == null">
        limit ${rows}
      </if>
    </if>
    这里limit ${offset}, ${rows}   对比 limit 20000 , 10
    即offset是偏移量,从第20001开始查询,查10条。 这里是limit 0,1000 从第一条开始查查询1000条

  • eg5
return Lists.partition(skuIds, 200).stream().map(skus -> {
	XxxDOExample example = new XxxDOExample();
example.createCriteria().andSkuIdIn(skus)
                    .andValidEqualTo(Boolean.TRUE);
            return example;
        }).map(example -> myMapper.selectByExample(example))
                .reduce((list1, list2) -> {
                    list1.addAll(list2);
                    return list1;
         }).orElse(Lists.newArrayList());

3、分页查询注意事项

只要使用分页查询,必须加上order by

1、原因

不使用order by,分页查询的数据不准确

  • 背景:

    select查询,如果不走二级索引查询,查询结果默认是按照主键id,正序排序;

    如果走了二级索引,则结果默认按二级索引排序展示

  • 问题复现

    select limit 0,5,使用了二级索引A进行查询,则结果按照索引A正序排序,为:7,8,9,1,2;

    又进行了select 5,10查询第二页;

    此时,因为数据库原因(主从切换,原本该走从查询的,现在走主查询了),或数据量变化(原本数据量级该走A索引查询的,现在走B索引查询了)

    select limit 5,5,使用了二级索引B进行查询,则结果按照索引B正序排序,为:11,12,13,14,2;导致id = 2的数据,在第一页 和 第二页分页查询结果中都出现了!!!甚至会导致数据丢失

2、解:

分页查询一定使用order by

3、SOP

3.1 分页查询全量数据(200、200、200 —)

  • 无脑order by id asc即可

  • 原因:

    此时如果order by 字段a,会有以下问题

    • 字段a,不是联合索引一员,导致走不到索引

    • 字段a,是联合索引一员,但是,中间断了x_y_z_a,但是本次查询条件仅有x_y ,order by a,也会使索引失效

    • 字段a,是联合索引一员,且连续,能走到索引,但是order by a字段,a字段有很多相同的数据。比如a字段为仓id

      select order by a ,limit 0, 5 ,结果为7,8,9,1,2

​ select order by a ,limit 5, 5 ,结果为2,11,12,13,14

​ 原因就是a字段有很多相同的数据,order by a,前后两页也有可能有相同数据

​ 比如联合索引为valid_poiId,select * from table where valid = 1 limit 0,200这个时候查出来的数据都是valid = 1的,因此查询结果会按照联合索引中的第二个字段poiId正序排序的!!!

即生效sql实际上为select * from table where valid = 1 order by poiId asc limit 0,200

问题:当poi_id有序增长时,id的增长并不有序,甚至可能跨度很大!!!,导致翻页时,如果使用了granThanId方式,取最后一条数据的id可能跳跃很大,导致漏数据。

复现:

查询结果 poiId id

​ 1 10009577 777

​ 2 10001014 77777777

这样即使查询出来的两条数据按poiId排序挨在一起,但是id却跨度很大很大。上一次granthanId的id为776,不会丢数据。这一次granThanid的id为77777777,id > 77777777,这样777- 77777777中间很多id的数据都没查出来!!!相当于丢数据了

所以,此时必须添加一个能确定顺序的索引,即order by a asc,id asc 。不如,直接order by id

3.2 分页查询全量数据,建议使用greathanId

3.3 如果是页面分页查询某一页的数据,而且需要字段a排序展示,则order by a asc,id asc文章来源地址https://www.toymoban.com/news/detail-731497.html

  • 原因:如果直接order by id,则查询出来的几条数据,不是按a字段排序的,可能不符合要求(a字段为销量,order by id查询出来的几条数据,销量可能不是最高的前几条)
example.setOrderByClause("poi_id asc, create_at asc");

到了这里,关于批量循环查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • scss语法,使用for循环批量设置class类

    现在我们写项目一般都是用scss写css,相关知识可以参考这篇文章。 scss中可以使用for循环批量设置具有相同规则的类,设计图中经常有不同透明度的颜色,如下: 我们就可以把不同透明度的颜色都设置成一个class,当然可以一个一个写,但是就很麻烦,所以我们可以使用scs

    2024年02月14日
    浏览(39)
  • DB SQL 转 ES DSL(支持多种数据库常用查询、统计、平均值、最大值、最小值、求和语法)...

    1. 简介   日常开发中需要查询 Elasticsearch 中的数据时,一般会采用 RestHighLevelClient 高级客户端封装的API。项目中一般采用一种或多种关系型数据库(如: Mysql 、 PostgreSQL 、 Oracle 等) + NoSQL(如: Elasticsearch )存储方案;不同关系数据库可以采用 Mybatis-Plus 方案屏蔽数据库的方言

    2024年01月17日
    浏览(51)
  • 在Azure SQL DB/Azure托管实例里快速查询各数据库大小以及每个数据库下表的大小

    目录 (一)前言 (二)正文 1. 环境: 2. 查看实例下每个数据库的空间大小 (1) SQL语法 (2)运行结果 3. 查看特定数据库下每张表的大小 (1)SQL语法 (2)运行结果 日常工作中对于各个数据库以及每一个数据库中下辖的表的大小,是我们日常监控以及分析问题的重要方向

    2024年02月11日
    浏览(69)
  • springboot+es批量新增、批量修改、根据内部id批量查询

    pom.xml配置 yml配置 EsConfig配置 ElasticSearchConfig 配置 启动类配置 //批量操作的对象 批量修改 批量新增 根据es内部id批量查询数据

    2024年02月11日
    浏览(51)
  • 域名批量查询功能常用查询方法教程

    一些用户在抱怨,要找到好域名怎么就那么不容易呢,能不能让我批量查下不含0的数字啊,能不能查下不含4的数字啊,能不能查下AABBB这样的域名啊…… 别着急,这就给您支招啦:通过西部数码强大的批量查询功能,您想要的米,统统都能查到。接下来就回答下大家长遇到

    2023年04月11日
    浏览(56)
  • ElasticSearch中批量操作(批量查询_mget、批量插入删除_bulk)

    有时候可以通过批量操作来减少网络请求。如:批量查询、批量插入数据。 当某一条数据不存在,不影响整体响应,需要通过found的值进行判断是否查询到数据。          在Elasticsearch中,支持批量的插入、修改、删除操作,都是通过_bulk的api完成的。 请求格式如下:(

    2024年02月12日
    浏览(49)
  • WordPress主题开发 — 模版循环(条件判断、多个循环、新建查询和文章循环)

            循环是 WordPress 通过主题模板文件输出文章的默认机制 。在循环中,WordPress 遍历当前页面获取到的所有文章,然后使用主题中的模版标签将其格式化并输出。 我们可以用 WordPress 循环来做很多事情,例如: 在网站首页显示多个文章模块 在文章详情页面显示内容

    2024年02月13日
    浏览(51)
  • 站长工具seo综合查询-批量查询域名扫描域名查询收录排名蜘蛛

    站长工具seo综合查询,什么是站长工具SEO查询?就是包含了站长平时用的所有功能,今天给大家分析一款全能的站长工具SEO综合查询包: 批量排名查询-批量网站收录查询-批量挖掘-批量文章采集-批量文章伪原创-批量文章发布到各大网站-主动推送搜索引擎收录

    2024年02月08日
    浏览(58)
  • ElasticSearch 批量查询

    一、背景: 最近部门业务调整,开始写一些后端接口,初次接触项目时,了解项目后端语音使用的Python,数据库使用的是es。 二、需求: 因为是刚接触这个项目,领导分了一个比较简单的需求让熟悉下项目,大致内容就是写一个批量查询的API,根据前端传过来的Id和Name列表,批

    2024年02月16日
    浏览(43)
  • elasticsearch批量删除(查询删除)

    注:delete by query只适用于低于elasticsearch2.0的版本(不包含2.0)。有两种形式: 1.无请求体 curl -XDELETE \\\'localhost:9200/twitter/tweet/_query?q=user:kimchy\\\' 2.有请求体 使用请求体的时候,请求体中只能使用query查询,不能使用filter curl -XDELETE \\\'localhost:9200/twitter/tweet/_query\\\' -d \\\'{ \\\"query\\\":{ \\\"term\\\":{\\\"user\\\":\\\"

    2024年02月10日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包