原!!mysql,几十万条数据中随机抽取1万以内的数据

想了几种方法:

1.将所有符合条件的对象集合都查出来,在代码里做随机。

2.先查出所有符合条件的id,再代码随机需要抽查数量的id,再 到数据库 中 in。

3.利用order by rand() limit ,随机出需要抽查数量的id,再到数据库中 in

 

条件过滤后,大概15万条数据,测试,第3种方法相对快,但是抽查数量到 7k, 8k, 1w 时候,第2种会稍微快点。

 知乎上:https://www.zhihu.com/question/20151242  建议用第2种

可能测试不够充分,待继续测试。。。

 public List<OpenMsgDo> getMsgList(QueryOpenMsgBean queryReq) {

        List<OpenMsgDo> exportList = new ArrayList<>();
        transform(queryReq);
        int randomSearchNum = Integer.parseInt(queryReq.getRandomSearchNum());

        log.info("查询的表名queryTableName=" + /*queryReq.getQueryTableName() + ", 符合查询条件的短信数量="
                                          + allIdsSize + */", 页面抽查的短信数量=" + randomSearchNum);

        //1.order by rand() limit 方式随机获取 id,再in
        //        long startTime2 = System.currentTimeMillis(); //开始测试时间
        List<Integer> randomIdsList2 = openMsgMapper.getRandomMsgIdsList(queryReq);
        if (randomIdsList2.size() > 0) {
            exportList = openMsgMapper.getMsgListByIds(queryReq.getQueryTableName(),
                    randomIdsList2);
        }
        //        long endTime2 = System.currentTimeMillis(); //获取结束时间     
        //        System.out.println("【【rand id 再in 方式 获取短信集合耗时: " + (double)(endTime2 - startTime2) / 1000 + "s】】");
        return exportList;

        /*   
         * 2.查出所有id,再随机id进去 ,in
         * long startTime = System.currentTimeMillis(); //开始测试时间
        List<Integer> allIdsList = openMsgMapper.getMsgIdsList(queryReq);
        int allIdsSize = allIdsList.size();
        if (allIdsSize > 0) {
            //随机抽取id
            List<Integer> randomIdsList = new ArrayList<>();
            log.info("查询的表名queryTableName=" + queryReq.getQueryTableName() + ", 符合查询条件的短信数量="
                    + allIdsSize + ", 页面抽查的短信数量=" + randomSearchNum);
            int max = allIdsSize;
            if (randomSearchNum < allIdsSize) {
                //随机抽取,再导出
                for (int i = 0; i < randomSearchNum; i++) {
                    int num = random.nextInt(max - i);//[0,max-i)
                    randomIdsList.add(allIdsList.get(num));
                    allIdsList.remove(num); //获得后去除,防止重复
                }
                log.info("实际随机抽取的短信数量=" + randomIdsList.size());
            } else {
                randomIdsList = allIdsList;
            }
            exportList = openMsgMapper.getMsgListByIds(queryReq.getQueryTableName(), randomIdsList);
            long endTime = System.currentTimeMillis(); //获取结束时间     
            System.out.println("【【获取所有id,随机抽取,再in 方式 获取短信集合耗时: " + (double)(endTime - startTime)/1000 + "s】】");
        }*/

        /*
         * 3.短信集合都查出来,再随机
         * transform(queryReq);
        List<OpenMsgDo> list = openMsgMapper.getMsgList(queryReq);
        int listSize = list.size();
        int randomSearchNum = Integer.parseInt(queryReq.getRandomSearchNum());
        log.info("查询的表名queryTableName=" + queryReq.getQueryTableName() + ", 符合查询条件的短信数量=" + listSize
                + ", 页面抽查的短信数量=" + randomSearchNum);
        
        int max = listSize;
        List<OpenMsgDo> exportList = new ArrayList<>();
        if (randomSearchNum < listSize) {
            //随机抽取,再导出
            Set<OpenMsgDo> set = new TreeSet<>();
            for (int i = 0; i < randomSearchNum; i++) {
                int num = random.nextInt(max - i);//[0,max-i)
                set.add(list.get(num));
                list.remove(num); //获得后去除,防止重复
            }
            log.info("实际随机抽取的短信数量=" + set.size());
            exportList.addAll(set);
        } else {
            exportList = list;
        }
        
        return exportList;*/
    }
原文地址:https://www.cnblogs.com/wuyun-blog/p/8399932.html