【性能优化】Mybatis Plus:优化查询速度之 SQL 替换 Service

【性能优化】Mybatis Plus:优化查询速度之 SQL 替换 Service

1、Service 接口问题

下面是原先的 Service 实现类代码,有门店 ID、订单状态、查询时间段,然后查出了所有的结果,继续使用 java8 的特性获取汇总结果,随着项目的推移,数据量越来越大,这种方式是不可取的,随便都能上几十秒查不出来,导致请求超时,下面我们就来优化一下这个方法

2、SQL 优化

先把上面的方法都转换成 SQL 语句的写法,得到下面的 5 个查询 SQL

select sum(A.pay_money) originPrice, count(A.id) countOrder, sum(A.pay_money) payMoney
from biz_order_info A
where A.`status` = 1 and A.order_status = 2 and A.store_id = 1;

select sum(A.pay_money) smPayMoney
from biz_order_info A
where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 1;

select sum(A.pay_money) rlPayMoney
from biz_order_info A
where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 2;

select sum(A.pay_money) sjPayMoney
from biz_order_info A
where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 3;

select sum(A.pay_money) xjPayMoney
from biz_order_info A
where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 4;

然后整理一下代码,通过union all连接,最简单的方法,后端使用 List 来接收返回值,有一定的可行性

select * from (
	(select sum(A.pay_money) 'value' from biz_order_info A where A.`status` = 1 and A.order_status = 2 and A.store_id = 1)
	union all
	(select count(A.id) 'value' from biz_order_info A where A.`status` = 1 and A.order_status = 2 and A.store_id = 1)
	union all
	(select sum(A.pay_money) 'value' from biz_order_info A where A.`status` = 1 and A.order_status = 2 and A.store_id = 1)
	union all
	(select sum(A.pay_money) 'value' from biz_order_info A where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 1)
	union all
	(select sum(A.pay_money) 'value' from biz_order_info A where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 2)
	union all
	(select sum(A.pay_money) 'value' from biz_order_info A where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 3)
	union all
	(select sum(A.pay_money) 'value' from biz_order_info A where A.`status` = 1 and A.order_status = 2 and A.store_id = 1 and A.pay_way = 4)
) X;

查询结果这样的

当我放到项目中时,发现还有查询条件,时间段,如果上面的 SQL 加上时间段,将会变的非常臃肿且难维护,所以上面的 SQL 报废了,不能使用,继续优化 SQL

-- 最开始的SQL
select A.*
from biz_order_info A
where A.`status` = 1 and A.order_status = 2;

-- 初步汇总,拿到3个我们需要的值
select sum(A.pay_money), count(A.id), sum(A.pay_money)
from biz_order_info A
where A.`status` = 1 and A.order_status = 2;

问题来了,怎么在已经查询出的结果中分支付方式汇总数据?

这里我使用的是 sum + case when 结构,分类汇总数据,再次优化 SQL

select sum(A.pay_money) originPrice, count(A.id) countOrder, sum(A.pay_money) payMoney,
sum(case A.pay_way when '1' THEN A.pay_money ELSE 0 END) smPayMoney,
sum(case A.pay_way when '2' THEN A.pay_money ELSE 0 END) rlPayMoney,
sum(case A.pay_way when '3' THEN A.pay_money ELSE 0 END) sjPayMoney,
sum(case A.pay_way when '4' THEN A.pay_money ELSE 0 END) xjPayMoney
from biz_order_info A
where A.`status` = 1 and A.order_status = 2

查询结果

接下来随便一箱,有两种方式处理业务逻辑了

  • 方法一:后台使用 Vo 实体类直接接收
  • 方法二:使用 Map 接收

下面是测试结果,Service 操作性能提升了 75.61% ,所以以后不要查询所有的数据!!!


优化后的接口代码

不要一次性查询所有表数据
一次性 SQL 解决的问题,就不要写 Service 方法了

微信公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tellsea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值