如何优化这种低效率的子查询?
select top 100
pno as 原料编号,
ord_qty as 采购数量,
price as 单价,
(select sum(qty) from tb_in where pno=a.pno) as 累计收货数量,
(select sum(back) from tb_in where pno=a.pno) as 累计退货数量,
(isnull((select sum(qty) from tb_in where pno=a.pno),0)-
isnull((select sum(back) from tb_in where pno=a.pno),0))
*price as 累计付款金额,
ord_qty -
isnull((select sum(qty) from tb_in where pno=a.pno),0) as 采购欠收数量,
(select ..........) as a,
(select ..........) as b,
(select ..........) as c,
(select ..........) as d,
(select ..........) as e,
(select ..........) as f,
(select ..........) as g,
(select ..........) as h,
(select ..........) as i
from tb_po a
where
(isnull((select sum(qty) from tb_in where pno=a.pno),0)-
isnull((select sum(back) from tb_in where pno=a.pno),0))>10000 and
isnull((select sum(back) from tb_in where pno=a.pno),0)=0
注:列出实际收货数量(已收数量-已退数量)大于10000,并且退货数量=0的采购记录
有时比这更复杂,有10多个子查询,效率无比低,请问大家有没有好的优化方法?
[解决办法]
额,前几天也遇到过相似的情况。请用inner join替代select sum(qty) from tb_in where pno=a.pno类似的语句,能大大提高性能。
[解决办法]
(select sum(qty) from tb_in where pno=a.pno) as 累计收货数量,
(select sum(back) from tb_in where pno=a.pno) as 累计退货数量,
都是在tb_in里选,为什么要分开计算呢?
select sum(qty),sum(back) 不行吗?
还有条件里
(select) 这种肯定性能不高啊。
条件里一般就是 字段 运算符 变量/常量 比如 date>'2012-12-21' ,type=1
[解决办法]
select top 100
pno as 原料编号,
ord_qty as 采购数量,
price as 单价,sum(qty) as qty,sum(back) as back,... from tb_po a join tb_in
on pno=a.pno
where ....
group by ...
order by ...
---其余的加减乘除运算可以先读表,根据查询结果再计算
into #t
from tb_in
group by pno
having sum(qty) > 10000
select top 100
a.pno as 原料编号,
a.ord_qty as 采购数量,
a.price as 单价,
b.qty as 累计收货数量,
b.back as 累计退货数量,
(b.qty-b.back)*price as 累计付款金额,
a.ord_qty -
b.qty as 采购欠收数量,
... as a,
... as b,
-- 下面自己改
(select ..........) as c,
(select ..........) as d,
(select ..........) as e,
(select ..........) as f,
(select ..........) as g,
(select ..........) as h,
(select ..........) as i
from tb_po a inner join #t b
on a.pno = b.pno
[解决办法]
group by需要运算和排序,的确会有很大开销,但是你应该考虑是否必须聚合运算,然后再去考虑性能问题。可以通过索引来增加性能。