我有以下存儲過程,在沒有子查詢的情況下運行時速度非常快。但是,我需要這些子選擇的結果來獲取我需要的信息。是否有另一種方法可以在不需要這些子查詢的情況下獲得這些結果,還是有任何方法可以使這些子查詢更加優化?使用子查詢更快地查詢
USE [macal]
GO
/****** Object: StoredProcedure [dbo].[APsp_MapaClientesSemanaUmCliente] Script Date: 26/02/2016 10:56:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[APsp_MapaClientesSemanaUmCliente]
@Vendedor varchar(20) = '',
@NoCliente int = 0,
@NoEstab int = 0
AS
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX);
DECLARE @ColumnName AS NVARCHAR(MAX);
--Get distinct values of the PIVOT Column
set @ColumnName = STUFF((
select ISNULL(@ColumnName + ',','')
--+','
+ QUOTENAME(courses.anomes)
FROM (SELECT DISTINCT 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2) anomes,row_number() over (order by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)) row FROM ft where ft.fdata >= DATEADD(week,-11, GETDATE())
group by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)
) Courses
FOR XML PATH('')
),1,1,'');
-- print @columnname
DECLARE @ColumnNameSelect AS NVARCHAR(MAX)
set @ColumnNameSelect = STUFF((
SELECT
',ISNULL('+QUOTENAME(courses.anomes)+',0) AS '+QUOTENAME('S'+ltrim(rtrim(str(courses.row))))
FROM
(
SELECT DISTINCT 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2) anomes,row_number() over (order by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)) row FROM ft where ft.fdata >= DATEADD(week,-11, GETDATE())
group by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)
) Courses
order by anomes
FOR XML PATH('')
),1,1,'');
--print @columnnameselect
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'SELECT
nome,
no,
estab,
morada,
telefone,
tlmvl,
contacto,
email,
ZonaVenda,
ZonaDist,
segmento,
classe,
descpp,
esaldo,
plafondseg,
pmr,
ref,
design,
unidade,
uni2,
peso,
u_uncx,
PrecoTab,
Desc1,
Desc2,
Desc4,
Preco,
DataPreco,
media_semana,
' + @ColumnNameSelect + '
FROM
(
select cl.nome,
ft.no,
ft.estab,
cl.morada,
cl.telefone,
cl.tlmvl,
cl.contacto,
cl.email,
cl.zona ZonaVenda,
cl.u_zonav ZonaDist,
cl.segmento,
cl.classe,
cl.descpp,
cl.esaldo,
cl.U_EPLAFSEG plafondseg,
ltrim(rtrim(str((select
case
when count(re.restamp) <> 0 then isnull(sum(datediff(dd,cc.datalc,re.procdata)),0)/count(re.restamp) else 0 end
from rl (nolock)
inner join re (nolock) on re.restamp = rl.restamp
inner join cc (nolock) on cc.ccstamp = rl.ccstamp
inner join cl (nolock) on cl.no = cc.no
where cl.no=ft.no and cl.estab=ft.estab and
re.process = 1 and
re.procdata >= convert(char(8), dateadd(mm, -12, getdate()), 112)
)))) PMR,
fi.ref,
st.design,
st.unidade,
st.uni2,
st.peso,
st.u_uncx,
isnull((select top 1 fix.epv from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) PrecoTab,
isnull((select top 1 fix.desconto from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Desc1,
isnull((select top 1 fix.desc2 from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Desc2,
isnull((select top 1 fix.desc4 from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Desc4,
isnull((select top 1 fix.etiliquido/fix.qtt from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Preco,
isnull((select top 1 ftx.fdata from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) DataPreco,
isnull((select avg(mytable.qtt) from
(
select ftx.no,ftx.estab,fix.ref,datepart(week,ftx.fdata) week,sum(case when ftx.tipodoc=3 then -fix.qtt else fix.qtt end) qtt
from ft(nolock) ftx,fi(nolock) fix where ftx.ftstamp=fix.ftstamp and ftx.no=ft.no and ftx.estab=ft.estab and fix.ref=fi.ref
and ftx.tipodoc=1 and ftx.fdata >= DATEADD(week,-11, GETDATE())
group by ftx.no,ftx.estab,fix.ref,datepart(week,ftx.fdata))
mytable
),0)
media_semana,
''S''+ltrim(rtrim(str(ft.ftano)))+right('+'''0'''+'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2) anomes,
fi.qtt
from fi,ft,st,cl
where
fi.ftstamp=ft.ftstamp and fi.ref=st.ref and cl.no=ft.no and cl.estab=ft.estab
and ft.fdata >= DATEADD(week,-23, GETDATE())
and ft.tipodoc=1
and fi.qtt<>0
and cl.no='+cast(@NoCliente as nvarchar(10))+'
and cl.estab='+cast(@NoEstab as nvarchar(10))+'
and cl.vendnm like case when '''[email protected]+''' = '+'''TODOS'''+' then '+'''%'''+' else '''[email protected]+''' end
) p
PIVOT(SUM(qtt)
FOR anomes IN (' + @ColumnName + ')) AS PVTTable
order by ref'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery
9倍於10 PIVOT是因爲人們試圖解決查詢中的表示問題。有機會,你可以在代碼層做很多工作,更好地用於演示。 –
數據透視表在速度方面創造了奇蹟,所以我不會專注於此。相反,我會去解決子查詢部分。 –
至少試試艾倫的建議。查詢太深使查詢優化器難以完成其工作。相反,填充你想要在一個臨時表中轉換的派生表,並在臨時表上進行轉換。它可能會提高性能。除此之外,你的查詢在許多層面都是錯誤的,所以這個問題有點「太寬泛」。 –