javaweb开发中,一些业务数据的查询,经常会有连表查询的需求、排序分组等,连表分页查询有个很严重的弊端:当表中数据量大到一定程度,由于计算量的指数型增加,会导致运算很慢,数据库压力随之增加。这时候需要将一条复杂sql拆分成多条简单sql,以减少运算量为目的的拆分。拆分原则:条件最早时机判定,减少连表,将分页后的数据值作为外键查询附属数据,进而提升sql执行效率。
这里的slq拆分分为两步:1.拆分sql。2.查询到的数据进行合并。
1.拆分:sql拆分中,我把它分为三类:一对一关系;一对多关系;多对多关系。
2.合并:同样的,通过拆分后的sql查询到的数据需要进行合并,将数据封装。分为三类:一对一;一对多;多对多。
拆分sql
例:
SELECT
i.id,i.sale_price...
FROM
yg_goods.`inventory` i
LEFT JOIN yg_goods.`goods` g
ON i.goods_id = g.`id`
LEFT JOIN yg_goods.`product` p
ON i.`product_id` = p.`id`
WHERE ...
ORDER BY i.id DESC
LIMIT 0, 10
有这么一条sql,假如where后的条件均在inventory表中,我们可以把它拆分为
select i.id,i.sale_price... from yg_goods.inventory i where ... order by i.id desc limit 0,10
select g.id... from yg_goods.goods g where g.id in ('上面主表sql查询到的goods_id集合')
select p.id... from yg_goods.product p where p.id in('上面主表sql查询到的product_id的集合')
如果where后的条件存在多个表,可以先将条件对应的外键id查询到,然后再将查询结果作为常量条件拆分后sql主表的外键限制,当然,这里的常量外键值最多不能超过1000,否则有可能不会提升运算效率,甚至降低性能。
以上是拆分的sql,查询出来的数据为三个list,三个list数据中,数据值是一对一的关系,这个时候我们可以将它合并。
将附属表信息的集合转换为map结构,然后循环主表中结果集,从map中根据外键获取附属表信息,进行设置。当然虽然可以实现,但要多些很多的非业务代码。平白增加工作量。我们可以将合并一对一关系,一对多关系,多对多关系的功能,抽取成一些工具方法,通用所有的javaBean及map。这样,我们只需要关注拆分,数据的合并,交给工具完成即可。