配置好连接池,mp我就直接测了
连接池版本1.1.22
mp版本3.4.3.4
mysql驱动 8.0.27
mysql版本5.7
先是两张一对一的表
插入10000条测试数据
方式1:手动查出来数据再遍历
然后用流的方式遍历id查询用户信息表,我试了很多次都是在21s多
方式2:left join查询
写好join的sql,因为id字段重复,必须手动映射
使用明显快了不少只要5.3s了 我也是试了很多次
方式3:mybatis自带子查询
只需要在association部分配置好select标签是哪个方法,column传什么参数过去,mybatis就会帮我们再查询拿到数据了
结果还是22s左右和方式1一样,我以前还一直以为这种子查询会快,结果和多次查询效率一样
方式4:另一种join关联方式
这和使用join是一样的
可以看到速度飞快,百度了下,这种方式和join是一样的,上面的join我习惯写成是left join虽然结果数据量相同,但是left join要放缓冲区后再查询再比对,所以效率低了点
最后一种情况,如果只需要表2的其中一条数据呢
结果是16s多
总结:最后还是join好,不过也得看需求,有的mysql集群,有的业务需求,不能join,left join,我网上很多人说子查询快(指的是在where后的)我就想当然觉得mybatis还能提供关联子查询,结果性能和正常手动再查一次差不多,被join吊打,当然还有一部分原因是配了连接池,要是没配连接池手动遍历估计会更慢就是了
还有我为什么用kotlin做测试,只是因为我创建springboot项目的时候看到了kotlin,我学后端前学了一段时间kotlin和安卓开发,今天看到就这个就想玩一玩,不过目前写这点代码倒是和java没什么差别就是了
目前只做了一对一关联测试,之后会做一对多的测试
现在是一对多关联
建一张订单表
给每个用户插入3条订单数据,总共3万条
方式1: 手动查出来数据再遍历
方式二:left join查询
方式三:mybatis自带子查询
方式4:另一种join查询
因为是一对多关联,表二数据不止一条,不能将要的数据防止select后,就没有
总结:只有join查询速度慢了一倍左右,别的都是原来的3倍 ,但是具体原因我就不了解了,有大佬可以给我讲讲
然后在关联字段添加上索引
一对一:
方式1:手动遍历21538ms->2373ms
方式2:left join 5042ms->492ms
方式3:mybatis子查询 21317ms->2342ms
方式4:join 433ms->429ms
方式5:select后的子查询 16587ms->394ms
看到,select后的子查询邮件和left join相当了,如果真的只要一个字段不join也好快,不过我不知道是否还有别的缓存什么的开销,还有join估计是没用走索引,误差范围了吗?我又去试了一下,直接在mysql里执行,加了索引是0.054s,不加是0.042s这就不理解了,加了索引还影响速度了,我不太了解,可能是索引加了开销又提高速度,但是索引失效造成的额外开销,而到代码中400多ms也不难理解就是映射1万条数据花的时间还有list的数组拷贝,既然映射花了400多ms,那么left join就也是映射开销问题,性能也是非常快
一对多:
方式1:手动遍历58636ms->2406ms
方式2:left join 13849ms->672ms
方式3:mybatis子查询 58289ms->2392ms
方式4:join 723ms->684ms
方式4好理解还是映射字段开销长还有list的数组拷贝,然后就是索引在一对多关联带来的巨大性能提升,mybatis子查询就很可观了,因为子查询可以指定成一个类,可以用带远程调用的方法,至于join确实是真的很快,看具体需求了
之后会再做一个直接在navicat上查询,忽略掉映射返回的影响,说不定会有截然不同的结果
我是菜逼,第一次写博客,有问题喷轻点