大数据量 分类统计每个类别的排名前三的数据
需求:
统计每个类别某项数据排名前几的数据
方案:
1、sql统计
2、sql查询出所有的数据,代码 group 分组取出每个类别的前3个数据
3、sql查询每个类别前3数据,union连接起来
4、sql查询查询出来所有的类型,根据类型查询出每个类型的前3个数据
测试:
表结构:
添加15万条测试数据:
@Beforepublic void getList() {long start = System.currentTimeMillis();Ranking user;for (int i = 1; i <= 3; i++) {for (int j = 1; j <=50000 ; j++) {user = new Ranking();user.setType(i);user.setNum(j);list.add(user);}}System.out.println("拼装数据 耗时:"+(System.currentTimeMillis()-start));System.out.println(list.size());}@Testpublic void batchInsert() {SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);RankMapper mapper = sqlSession.getMapper(RankMapper.class);System.out.println("batchInsert 插入开始========");long start = System.currentTimeMillis();for (int i = 0; i < list.size(); i++) {mapper.insert(list.get(i));if (i%5000==4999) {sqlSession.flushStatements();}}sqlSession.flushStatements();System.out.println("SqlSession 批量插入耗时:"+(System.currentTimeMillis()-start));}
方案1:
SELECTa.type,a.num
FROMranking AS a
WHERE(SELECTCOUNT(*)FROMranking AS bWHEREb.type = a.typeAND b.num >= a.num) <= 3
ORDER BYa.type ASC,a.num DESC;
因为涉及子查询,查询效率太低,几分钟后sql还是没有执行完毕。。
方案2:
先使用mybatis-plus 查询出所有的数据,使用分组统计出每个类别前三的数据。
@Testpublic void testRankSelect() {long start = System.currentTimeMillis();List<Ranking> rankings = rankMapper.selectList(null);long end = System.currentTimeMillis();System.out.println("查询15万数据查询时间:"+(end-start));System.out.println("分组开始================");List<Ranking> rankingresult = new ArrayList<>();Map<Integer, List<Ranking>> typeGroup = rankings.stream().collect(Collectors.groupingBy(Ranking::getType));typeGroup.forEach((k,v)->{List<Ranking> v1 = v;v1.sort(Comparator.comparing(Ranking::getNum).reversed());v1 = v1.subList(0,3);rankingresult.addAll(v1);});long groupEnd = System.currentTimeMillis();System.out.println("分组统计前三花费时间:"+(groupEnd-end));System.out.println(rankingresult);}
效果:15万条数据,查询加上分组统计大约花费2秒;用sql时间应该在1秒之内
方案3:
分别查询出3个类别前3的数据,然后union起来
(SELECT type,num from ranking where type = 1 order by num desc limit 3)
union
(SELECT type,num from ranking where type = 2 order by num desc limit 3)
union
(SELECT type,num from ranking where type = 3 order by num desc limit 3)
在类别不多的情况下,使用此种方式,3个类别,15万条数据 执行时间0.12秒
方案4:
先sql查询出来所有的类型,根据类型遍历查询每个类型的前3条数据,将查询出来的数据放入list中
@Testpublic void queryWrapperRankSelect() {long start = System.currentTimeMillis();QueryWrapper<Ranking> queryWrapper = new QueryWrapper<>();queryWrapper.select("distinct type");List<Ranking> rankTypes = rankMapper.selectList(queryWrapper);List<Ranking> rankingresult = new ArrayList<>();rankTypes.forEach(e->{LambdaQueryWrapper<Ranking> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.eq(Ranking::getType,e.getType());lambdaQueryWrapper.orderByDesc(Ranking::getNum);lambdaQueryWrapper.last("limit 3");List<Ranking> rankings = rankMapper.selectList(lambdaQueryWrapper);rankingresult.addAll(rankings);});long end = System.currentTimeMillis();System.out.println("分组统计前三花费时间:"+(end-start));System.out.println(rankingresult);}
效果:查询处理数据大约花费0.7秒
总结:
若是需求允许,并且类别固定且数量少的情况下,使用方案3效率最高(灵活性低,类别固定情况下可以使用);
其次就是方案4,先sql查询出来所有的类型,根据类型遍历查询每个类型的前3条数据,将查询出来的数据放入list中,效率高(建议使用)。
然后就是使用方案2,先查询出来所有的数据,在分组求每个类别的前3的数据,效率也挺高的(建议使用)。
最后就是方案1,使用sql直接计算出结果,效率最低,如果数据量大的情况下程序可能会崩溃(不建议使用)。
大数据量 分类统计每个类别的排名前三的数据相关推荐
- NeurIPS 2017 论文 2018 年引用量排名揭晓,这里是排名前三的论文解读...
雷锋网 AI 科技评论按,12 月上旬,NeurIPS 2018 在加拿大蒙特利尔会展中心(Palais des Congrès de Montréal)成功举办,雷锋网对此进行了报道.今年的会议在主 ...
- 第一百三十九期:11月数据库排行:排名前三数据库分数暴跌
DB-Engines 数据库流行度排行榜 11 月更新已发布,与上期数据相比,这期排行榜最大的亮点就是排名前三数据库那引人注目的"红色"分数. 作者:局长 DB-Engines 数 ...
- MySQL获取每个分类下面的前三条数据
现在项目遇到个问题,我相册图片里面有很多分类,我想取出每个分类下面的前三条数据,应该怎么做呢? 数据结构如下: DROP TABLE IF EXISTS `t_picture`; CREATE TAB ...
- 【SQL开发实战技巧】系列(十四):计算消费后的余额计算银行流水累计和计算各部门工资排名前三位的员工
系列文章目录 [SQL开发实战技巧]系列(一):关于SQL不得不说的那些事 [SQL开发实战技巧]系列(二):简单单表查询 [SQL开发实战技巧]系列(三):SQL排序的那些事 [SQL开发实战技巧] ...
- 全国各省排名前三的高校!有你的目标学院校吗?
择校是一个无法一步到位的过程,因为随着了解的不断深入,有的同学会有一些不同的想法,有时候会选择去不同的城市.不一样的学校.甚至变其他的专业. 但是无论你如何选择,你的分数能越高,选择的余地就更大,今天 ...
- 雅安职业技术学院工业机器人专业_雅安职业技术学院排名前三的专业有哪些
雅安职业技术学院简介 雅安职业技术学院有六十年的办学经验,学校到目前已经厚积了丰富的办学资源.办学经验和办学的实力,是一所全日制公办的高等职业学校.学校的师资队伍也是非常好,不仅教学经验丰富还非常认真 ...
- 全球银行市值排行榜:工建中排名前三
金融风暴下,中资银行的实力再次惹人注意.日前,根据德国<法兰克福汇报>的报道,在全球银行市值排行榜上,中国工商银行.中国建设银行.中国银行排名前三. 该报道称,金融危机严重打乱了世界大银行 ...
- mysql分组取出每组地一条数据_MySQL 分组后取每组前N条数据
与oracle的rownumber() over(partition by xxxorder by xxx)语句类似,即:对表分组后排序 创建测试emp表 DROP TABLE IF EXISTS e ...
- 查询总成绩排名前三的学生成绩信息
面试的时候碰到一个笔试题,一张学生成绩表A(表可以自行脑补,就这个意思),如图(学生,课程,分数): 要查出总分排名前三的学生成绩信息. 首先是要查出总分前三的学生: SELECT name from ...
最新文章
- 大脑认知能力获突破进展!《科学》发现促进大脑发育期间的关键细胞器
- 数据结构实验之栈与队列八:栈的基本操作
- range与enumerate的区别
- 手写vue2的Lazyload
- HoloLens开发手记-全息Hologram
- [JavaWeb-JavaScript]JavaScript_Function函数(方法)对象
- python我想对你说_python学习第3天-----字典、解构
- python求组合数c_科学网—Python 组合函数 C(n,m) - 杨玠的博文
- mtk 驱动(55)---mtk指纹移植
- oracle建库并使用HR范例,Oracle HR样例数据库建立
- FusionCharts的使用方法
- python面试题-如“上海 深圳 深圳 上海“,要求输入一个匹配模式,比如: aabb,判断是否符合
- 邓俊辉数据结构学习笔记3-二叉树
- 法律硕士毕业论文应该怎么写?
- Linux入门参考文档(超详细)
- 华为mate30pro和荣耀v30pro的区别 哪个好
- 怎样在VS2005中添加Flash控件
- 唐诗页面爬取 --- 预研阶段
- MPAndroidChart的详细使用——BarChart条形图组(三)
- Sql Server 2008 R2 清理内存的三种方法