使用union来代替字段嵌套子查询优化
2017-09-26 14:08
309 查看
以前写过一条关于任务指标的sql,这个关于查询任务目标,任务达成情况和任务完成比例的一个查询sql,因为查询的任务包括了3个方面 销售额 开卡数量和微信加粉数量的一个任务查询 所以关联的表比较多,最后需要做的一个结果展示效果如下:
需要查询出这样的信息,每个用户进来可以查询到自己的任务情况 ,我以前的做法是先使用派生表把这个任务关于自己的信息查询出来,再通过字段上面使用嵌套子查询来完成的,为了看起来直观,语句如下:
select
任务.任务名称,
任务.任务开始时间,
任务.任务结束时间,
任务.目标销售额,
(select sum(订单表.结算金额) from 订单表 left join 任务从表 on 任务从表.uid=订单表.完成人 where 订单表.完成人="张三")as 完成销售额,
(count(5)/任务.销售额*100 )as 完成销售比例(%),
任务.目标开卡数,
(select count(会员表.id) from 会员表 left join 任务从表 on 会员表.业务员id=任务从表.uid where 任务从表.uid="张三")as 完成开卡数,
(count(8)/任务.目标开卡数*100)as 开卡完成比例(%),
任务.目标加粉数,
(select count(加粉中间表.会员id) from 加粉中间表 left join 任务从表 on 加粉中间表.uid="张三" ) as 完成加粉数,
(count(11)/任务.目标加粉数*100)as 加粉数完成比例(%)
from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as 任务
当时的sql就是把查询的结果,比如销售额的完成情况和完成的比例这些都写在了字段上面去进行查询,这样的弊端就是如果
bb7d
一旦数据量庞大之后,查询效率会非常受影响,甚至会出现服务器宕机的情况,所以考虑到以后会出现的这些情况,需要对该条语句进行优化,听了我们组长的提示,他说可以使用union来做,最后经过思考和组长的指导,将上面的语句优化成了以下的格式:
由以前的横向转成了纵向,返回的结果可以使用list来接收,根据name的名字来做条件,计算每样指标完成的百分比,因为再java程序里做计算和数据库相比,后者效率更高,特别是再数据量庞大的情况,因为某些情况计算会使索引失效而导致全表扫描 sql 如下:
select '任务名称' as name,task.任务名称 as value from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task
union all
select '任务开始时间' as name,task.任务开始时间 from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task
union all
select '目标销售额' as name,task.目标销售额 from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task
union all
select '完成销售额' as name,sum(订单表.结算金额) from 订单表 left join
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task on 订单表.完成人=task.uid
union all
。。。。。。(需要关联查询的数据)
嵌套子查询的查询相当于乘法,比如A表10条数据,B表10条数据,如果没有使用索引相当于全表扫描查询 也就是10*10的概念,而union的查询则有点像加法,A表的查询+B表的查询。所以再数据量较小的情况基本没有什么区别 就像2+2=2*2的概念一样而如果1000*1000和1000+1000 那样查询效率的结果会非常明显。
所以有些时候也是需要根据实际情况来做调整的,但都是选择最优,最快的方案来执行。
需要查询出这样的信息,每个用户进来可以查询到自己的任务情况 ,我以前的做法是先使用派生表把这个任务关于自己的信息查询出来,再通过字段上面使用嵌套子查询来完成的,为了看起来直观,语句如下:
select
任务.任务名称,
任务.任务开始时间,
任务.任务结束时间,
任务.目标销售额,
(select sum(订单表.结算金额) from 订单表 left join 任务从表 on 任务从表.uid=订单表.完成人 where 订单表.完成人="张三")as 完成销售额,
(count(5)/任务.销售额*100 )as 完成销售比例(%),
任务.目标开卡数,
(select count(会员表.id) from 会员表 left join 任务从表 on 会员表.业务员id=任务从表.uid where 任务从表.uid="张三")as 完成开卡数,
(count(8)/任务.目标开卡数*100)as 开卡完成比例(%),
任务.目标加粉数,
(select count(加粉中间表.会员id) from 加粉中间表 left join 任务从表 on 加粉中间表.uid="张三" ) as 完成加粉数,
(count(11)/任务.目标加粉数*100)as 加粉数完成比例(%)
from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as 任务
当时的sql就是把查询的结果,比如销售额的完成情况和完成的比例这些都写在了字段上面去进行查询,这样的弊端就是如果
bb7d
一旦数据量庞大之后,查询效率会非常受影响,甚至会出现服务器宕机的情况,所以考虑到以后会出现的这些情况,需要对该条语句进行优化,听了我们组长的提示,他说可以使用union来做,最后经过思考和组长的指导,将上面的语句优化成了以下的格式:
由以前的横向转成了纵向,返回的结果可以使用list来接收,根据name的名字来做条件,计算每样指标完成的百分比,因为再java程序里做计算和数据库相比,后者效率更高,特别是再数据量庞大的情况,因为某些情况计算会使索引失效而导致全表扫描 sql 如下:
select '任务名称' as name,task.任务名称 as value from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task
union all
select '任务开始时间' as name,task.任务开始时间 from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task
union all
select '目标销售额' as name,task.目标销售额 from
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task
union all
select '完成销售额' as name,sum(订单表.结算金额) from 订单表 left join
(select 任务主表.id,任务主表.任务名称,任务主表.任务开始时间,任务主表.结束时间,任务从表.目标销售额,任务从表.目标开卡数,任务从表.目标加粉数 from 任务主表 left join 任务从表 on 任务主表id=任务从表.taskid) as task on 订单表.完成人=task.uid
union all
。。。。。。(需要关联查询的数据)
嵌套子查询的查询相当于乘法,比如A表10条数据,B表10条数据,如果没有使用索引相当于全表扫描查询 也就是10*10的概念,而union的查询则有点像加法,A表的查询+B表的查询。所以再数据量较小的情况基本没有什么区别 就像2+2=2*2的概念一样而如果1000*1000和1000+1000 那样查询效率的结果会非常明显。
所以有些时候也是需要根据实际情况来做调整的,但都是选择最优,最快的方案来执行。
相关文章推荐
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- 使用UNION代替OR 提升查询性能
- 使用嵌套子查询优化hive的SQL
- 注意使用 BTREE 复合索引各字段的 ASC/DESC 以优化 order by 查询效率
- 注意使用 BTREE 复合索引各字段的 ASC/DESC 以优化 order by 查询效率
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- SQL联合查询优化 用union all来代替union
- 注意使用 BTREE 复合索引各字段的 ASC/DESC 以优化 order by 查询效率
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- SQL优化--使用关联查询代替子查询
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- 数据查询使用数字代替字段排序
- 数据查询使用数字代替字段排序
- 使用UNION代替OR 提升查询性能
- 使用EXISTS代替JOIN优化查询速度
- 使用or展开进行sql优化(即sql语法union all代替or可以提高效率)
- 使用union all查询时字段不匹配解决办法
- 数据库优化union连表查询返回同一个字段
- 注意使用 BTREE 复合索引各字段的 ASC/DESC 以优化 order by 查询效率
- BLOB或TEXT字段使用散列值和前缀索引优化提高查询速度