我使用这个select语句来收集来自不同表的信息,但是在它们之间保持相同的结构并最终对结果进行分组,但是因为" fi" table有数千行,处理结果需要很长时间。有没有办法优化下面的查询以获得更快的结果?
Milk
Work
Chair
...
答案 0 :(得分:0)
1) 是数据类型varchar的ft.fdata吗?如果是数字,请使用
and ft.fdata between 20160301 and 20160331
而不是
and ft.fdata between '20160301' and '20160331'
2) 有什么用?这对我没有意义。
and isnull(sz.nome,'') like '%' + + '%'
3)与性能无关,但我建议您不要使用ORDER BY ColumnNumber
order by 1,2,3,4,6,7
4)在列中进行子选择(下面的代码示例)通常是关于性能的一个非常糟糕的主意。如果可能,尝试将其用作子查询。
isnull((select sum(case when sl.cm=1 then sl.qtt else 0 end) from sl (nolock) where sl.ref=bi.ref and sl.cor=bi.cor and sl.tam=bi.tam and sl.datalc<='20160331'),0) EntregueSede
5)检查指数(已经由其他人推荐)
6)有时候查询与“all all”或“union”相结合往往会破坏执行计划(根据我的经验)。如果首先将每个查询加载到临时表中然后组合临时表,通常会有所帮助。没有多少时间尝试它,所以它可以帮助你。
编辑:
这里是第4点的例子:
Select
isnull(ST.REF,'') as Referencia
, fi.design as Designacao
, fi.cor Cor
, fi.tam Tamanho
, sum(case when ft.tipodoc=3 then -fi.qtt else fi.qtt end) as Qtd
, isnull(EntregueSedeData.EntregueSedeSum ,0) EntregueSede -- <----- USE HERE THE SUM
, isnull((select sum(case when sl.cm<50 then sl.qtt when sl.cm>50 then -sl.qtt else 0 end) from sl (nolock) where sl.ref=fi.ref and sl.cor=fi.cor and sl.tam=fi.tam and sl.datalc<='20160331'),0) Stock
from fi (nolock)
inner join -- <----- JOIN YOUR DATA WITH CALCULATED SUM
(
select fi.ref,
fi.cor,
fi.tam,
sum(
case
when sl.cm = 1 then sl.qtt
else 0
end
)
as EntregueSedeSum
from sl (nolock)
where sl.datalc <= '20160331'
) EntregueSedeData
on sl.ref=fi.ref
and sl.cor=fi.cor
and sl.tam=fi.tam
inner join ft (nolock) on ft.ftstamp=fi.ftstamp
inner join td (nolock) on ft.ndoc=td.ndoc and td.regrd=0
left join st (nolock) on fi.ref = st.ref or fi.oref = st.ref
left join sz (nolock) on sz.no = fi.armazem
where fi.composto=0
and ft.fdata between '20160301' and '20160331'
and ft.anulado=0
and ft.fno>=0
and fi.qtt<>0
and ft.tipodoc in(1, 2, 3)
and ((FI.ARMAZEM between 1000 and 1999) or fi.armazem in(10,20))
and isnull(sz.nome,'') like '%' + + '%'
group by FI.REF, fi.design,fi.cor,fi.tam,st.ref
这里是第6点的例子:
create table #P1 -- replace xxx by your data type and add NOT NULL where possible
(
Referencia xxx PRIMARY KEY NOT NULL, -- don't know your data model, if Referencia is unique, use it the primary key
Designacao xxx
Cor xxx,
Tamanho xxx,
EntregueSede xxx,
Stock xxx
)
insert into #P1
(
Referencia,
Designacao,
Cor,
Tamanho,
EntregueSede,
Stock
)
Select
isnull(ST.REF,'') as Referencia
, fi.design as Designacao
, fi.cor Cor
, fi.tam Tamanho
, sum(case when ft.tipodoc=3 then -fi.qtt else fi.qtt end) as Qtd
, isnull((select sum(case when sl.cm=1 then sl.qtt else 0 end) from sl (nolock) where sl.ref=fi.ref and sl.cor=fi.cor and sl.tam=fi.tam and sl.datalc<='20160331'),0) EntregueSede
, isnull((select sum(case when sl.cm<50 then sl.qtt when sl.cm>50 then -sl.qtt else 0 end) from sl (nolock) where sl.ref=fi.ref and sl.cor=fi.cor and sl.tam=fi.tam and sl.datalc<='20160331'),0) Stock
from fi (nolock)
inner join ft (nolock) on ft.ftstamp=fi.ftstamp
inner join td (nolock) on ft.ndoc=td.ndoc and td.regrd=0
left join st (nolock) on fi.ref = st.ref or fi.oref = st.ref
left join sz (nolock) on sz.no = fi.armazem
where fi.composto=0
and ft.fdata between '20160301' and '20160331'
and ft.anulado=0
and ft.fno>=0
and fi.qtt<>0
and ft.tipodoc in(1, 2, 3)
and ((FI.ARMAZEM between 1000 and 1999) or fi.armazem in(10,20))
and isnull(sz.nome,'') like '%' + + '%'
group by FI.REF, fi.design,fi.cor,fi.tam,st.ref
create table #P2 -- replace xxx by your data type and add NOT NULL where possible
(
Referencia xxx PRIMARY KEY NOT NULL, -- don't know your data model, if Referencia is unique, use it the primary key
Designacao xxx
Cor xxx,
Tamanho xxx,
EntregueSede xxx,
Stock xxx
)
insert into #P2
(
Referencia,
Designacao,
Cor,
Tamanho,
EntregueSede,
Stock
)
Select
isnull(ST.REF,'') Referencia
, fi.design Designacao
, fi.cor Cor
, fi.tam Tamanho
,sum(case when ft.tipodoc=3 then -fi.qtt else fi.qtt end) as Qtd
, isnull((select sum(case when sl.cm=1 then sl.qtt else 0 end) from sl (nolock) where sl.ref=fi.ref and sl.cor=fi.cor and sl.tam=fi.tam and sl.datalc<='20160331'),0) EntregueSede
, isnull((select sum(case when sl.cm<50 then sl.qtt when sl.cm>50 then -sl.qtt else 0 end) from sl (nolock) where sl.ref=fi.ref and sl.cor=fi.cor and sl.tam=fi.tam and sl.datalc<='20160331'),0) Stock
from fi (nolock)
inner join ft (nolock) on ft.ftstamp=fi.ftstamp
inner join td (nolock) on ft.ndoc=td.ndoc and td.regrd=0
left join st (nolock) on fi.ref = st.ref or fi.oref = st.ref
left join sz (nolock) on sz.no = fi.armazem
where fi.composto=0
and ft.fdata >= '20150505'
and ft.fdata between '20160301' and '20160331'
and ft.anulado=0
and ft.fno>=0
and fi.qtt<>0
and ft.ndoc in (401,501)
and isnull(sz.nome,'') like '%' + + '%'
group by FI.REF, fi.design, fi.cor, fi.tam, st.ref
create table #P3 -- replace xxx by your data type and add NOT NULL where possible
(
Referencia xxx PRIMARY KEY NOT NULL, -- don't know your data model, if Referencia is unique, use it the primary key
Designacao xxx
Cor xxx,
Tamanho xxx,
EntregueSede xxx,
Stock xxx
)
insert into #P3
(
Referencia,
Designacao,
Cor,
Tamanho,
EntregueSede,
Stock
)
select
isnull(ST.REF,'') Referencia
, bi.design as Designacao
, bi.cor Cor
, bi.tam Tamanho
,sum(bi.qtt) as Qtd
, isnull((select sum(case when sl.cm=1 then sl.qtt else 0 end) from sl (nolock) where sl.ref=bi.ref and sl.cor=bi.cor and sl.tam=bi.tam and sl.datalc<='20160331'),0) EntregueSede
, isnull((select sum(case when sl.cm<50 then sl.qtt when sl.cm>50 then -sl.qtt else 0 end) from sl (nolock) where sl.ref=bi.ref and sl.cor=bi.cor and sl.tam=bi.tam and sl.datalc<='20160331'),0) Stock
from bi(nolock)
inner join bo(nolock) on bo.bostamp = bi.bostamp
inner join bo2(nolock) on bo2stamp = bo.bostamp
inner join ts(nolock) on ts.ndos = bo.ndos and ts.ndos = 60
left join st(nolock) on bi.ref = st.ref
left join sz(nolock) on sz.no = bi.armazem
where bi.composto=0
and bo.dataobra between '20160301' and '20160331'
and bo2.anulado= 0
and bo.obrano >= 0
and bi.qtt<>0
and isnull(sz.nome,'') like '%' + + '%'
group by bi.REF, bi.design, bi.cor, bi.tam, st.ref
select Referencia,
Designacao,
cor,
Tamanho,
sum(qtd),
entreguesede,
stock
from
(
select
Referencia,
Designacao,
Cor,
Tamanho,
EntregueSede,
Stock
from #P1
union all
select
Referencia,
Designacao,
Cor,
Tamanho,
EntregueSede,
Stock
from #P2
union all
select
Referencia,
Designacao,
Cor,
Tamanho,
EntregueSede,
Stock
from #P3
) a
group by Referencia,
Designacao,
cor,
Tamanho,
entreguesede,
stock
order by 1,2,3,4,6,7