나는 최적화 할이 쿼리를최적화
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ComprobantesFacturasObtenerEstadisticasLocal2]
(
@FechaDesde DateTime,
@FechaHasta DateTime,
@XML ntext
)
AS
BEGIN
DECLARE @docHandler INT
EXEC sp_xml_preparedocument @docHandler OUTPUT, @XML
--Locales
Select IdLocal
into #seleccionados
FROM OPENXML(@docHandler, N'/NewDataSet/Table1', 2)
WITH (IdLocal int)
select d.* into #Locales from Dim_Sucursal d inner join GrimRepCen..Locales l on l.Codigo = d.Codigo inner join #seleccionados s on s.IdLocal = l.iDlocal
/*2011/12/06 busco los descuentos del rio*/
select distinct l.Codigo + ' - ' + l.Nombre as local, c.IdComprobante, -1 as Cantidad,
-1 * isnull(abs(c.TotalNeto),0) as IMPORTE,
'Varios' as Familia, 'Dto Bco Rio' as Linea
into #descuentoRio
from Fact_Comprobante(nolock) c
--inner join Fact_ComprobanteItem(nolock) ci on ci.IdComprobante = c.IdComprobante
inner join #locales l on c.idDim_ComprobanteTipo = 5 and l.IdDim_sucursal = c.IdDim_sucursal and c.fecha between @FechaDesde and @FechaHasta
/*******************COMPROBANTES************************************************ */
select distinct
c.*, l.Codigo + ' - ' + l.Nombre as local, ct.IdComprobanteTipo
into #Comprobantes
from Fact_Comprobante(nolock) c
inner join Fact_ComprobanteItem(nolock) ci on ci.IdCOmprobante = c.IdComprobante
inner join Dim_ComprobanteTipo(nolock) ct on ct.IdDim_ComprobanteTipo = c.idDim_ComprobanteTipo
inner join #locales l on l.IdDim_sucursal = c.IdDim_sucursal and ct.IdComprobanteTipo not in (46 /*Error Fiscal Factura B*/, 47 /*Error Fiscal Factura A*/) and c.fecha between @FechaDesde and @FechaHasta
--Comprobantes por Linea/Marca/Familia
select
m.Nombre as Marca, l.Nombre as Linea , case when c.IdComprobanteTipo in (21,23,26,28) then 0 else -sum(ci.Cantidad) end as Cantidad,
case when c.IdComprobanteTipo in (21,23,26,28)
--toma en cuenta los descuentos de las facturas que fueron anuladas
then c.TotalNeto
else isnull(ci.ImporteNeto,0) - isnull((select sum(importe) as importe
from Fact_Descuento (nolock) DD
where DD.IdComprobante = ci.idComprobante and ci.IdDim_Producto = IdDim_Producto
and ci.IdDim_Medida = IdDim_Medida and ci.IdDim_Calidad = IdDim_Calidad
and exists
(
select 1
from ComprobanteReferencias AA
inner join Fact_Comprobante BB on aa.IdComprobanteCredito = BB.IdComprobante
where AA.IdComprobanteDebito = DD.IdComprobante
and BB.IdDim_ComprobanteTipo in (4,13,16,19)
)
),0)
end as IMPORTE,
f.Nombre as Familia
from #Comprobantes c
inner join Fact_ComprobanteItem(nolock) ci on ci.IdComprobante = c.IdComprobante
inner join Dim_Producto(nolock) p on p.IdDim_Producto = ci.IdDim_Producto
inner join Dim_Marca(nolock) m on m.IdDim_Marca = p.IDDim_Marca
inner join Dim_Familia(nolock) f on f.idDim_Familia = p.IdDim_Familia
inner join Dim_Linea(nolock) l on l.IdDim_Linea = p.IdDim_Linea
Group by m.Nombre,l.Nombre,f.Nombre,c.TotalNeto,ci.IdComprobante, ci.IdDim_producto,
ci.idDim_Medida,ci.ImporteNeto,c.IdComprobanteTipo ,ci.IdDim_Calidad
union all
select 'Grimoldi' as Marca, Linea , - 1 Cantidad,
IMPORTE,
Familia
from #descuentoRio
--/*Familia*/
select case when c.IdComprobanteTipo in (21,23,26,28) then 0 else -isnull(sum(ci.Cantidad),0) end as Cantidad,
case when c.IdComprobanteTipo in (21,23,26,28)
--toma en cuenta los descuentos de las facturas que fueron anuladas
then c.TotalNeto
else isnull(ci.ImporteNeto,0) - isnull((select sum(importe) as importe
from Fact_Descuento (nolock) DD
where DD.IdComprobante = ci.idComprobante and ci.IdDim_Producto = IdDim_Producto
and ci.IdDim_Medida = IdDim_Medida and ci.IdDim_Calidad = IdDim_Calidad
and exists
(
select 1
from ComprobanteReferencias AA
inner join Fact_Comprobante BB on aa.IdComprobanteCredito = BB.IdComprobante
where AA.IdComprobanteDebito = DD.IdComprobante
and BB.IdDim_ComprobanteTipo in (4,13,16,19)
)
),0)
end as IMPORTE,
f.Nombre as Familia
from #Comprobantes c
inner join Comprobantes(nolock) co on co.IdComprobante = c.IdComprobante
inner join Fact_ComprobanteItem(nolock) ci on ci.IdComprobante = c.IdComprobante
inner join Dim_Producto(nolock) p on p.IdDim_Producto = ci.IdDim_Producto
full outer join Dim_Familia(nolock) f on f.idDim_Familia = p.IdDim_Familia
Group by f.Nombre,ci.ImporteNeto,ci.IdComprobante, ci.IdDim_producto,
ci.idDim_Medida,c.TotalNeto, c.IdComprobanteTipo ,ci.IdDim_Calidad
union all
select -1 as Cantidad,
IMPORTE,
Familia
from #descuentoRio
/*local*/
select c.Local, case when c.IdComprobanteTipo in (21,23,26,28) then 0 else -isnull((sum(ci.Cantidad)),0) end as Cantidad,
case when c.IdComprobanteTipo in (21,23,26,28)
--toma en cuenta los descuentos de las facturas que fueron anuladas
then c.TotalNeto
else isnull(ci.ImporteNeto,0) - isnull((select sum(importe) as importe
from Fact_Descuento (nolock) DD
where DD.IdComprobante = ci.idComprobante and ci.IdDim_Producto = IdDim_Producto
and ci.IdDim_Medida = IdDim_Medida and ci.IdDim_Calidad = IdDim_Calidad
and exists
(
select 1
from ComprobanteReferencias AA
inner join Fact_Comprobante BB on aa.IdComprobanteCredito = BB.IdComprobante
where AA.IdComprobanteDebito = DD.IdComprobante
and BB.IdDim_ComprobanteTipo in (4,13,16,19)
)
),0)
end as IMPORTE,
f.Nombre as Familia, l.Nombre as Linea
from #Comprobantes c
inner join Comprobantes(nolock) co on co.IdComprobante = c.IdComprobante
inner join Fact_ComprobanteItem(nolock) ci on ci.IdComprobante = c.IdComprobante
inner join Dim_Producto(nolock) p on p.IdDim_Producto = ci.IdDim_Producto
inner join Dim_Linea(nolock) l on l.IdDim_Linea = p.IdDim_Linea
inner join Dim_Familia(nolock) f on f.idDim_Familia = p.IdDim_Familia
Group by f.Nombre,ci.ImporteNeto, l.Nombre ,ci.IdComprobante, ci.IdDim_producto,
ci.idDim_Medida, c.Local,c.TotalNeto, c.IdComprobanteTipo,ci.IdDim_Calidad
union all
select Local, -1 as Cantidad,
IMPORTE,
Familia, Linea
from #descuentoRio
end
어떤 내가 다른 방법 대신 XML의 id의를 전송, 예를 들어, 변경할 수 없습니다 것을 (I 때문에이있다 코드를 수정해야만 할 수 있습니다.), 테이블 및 기타 물건의 구조. 나는 단지 이것을 저장할 수있다. 이 쿼리는 일부 ID를 수신하고 임시 테이블 (#Seleccionados
)에 삽입하고 일부 조인을 사용하여 영업 및 기타 정보를 얻습니다. 또한 이상한 일, harcoded 값이있는 Union ALL 및 다른 것들을 볼 수 있습니다. 그 이유는 코드의 보고서가 수행 된 방식과이를 변경할 수 없기 때문입니다. (이상한 일은 걱정하지 않아도됩니다.) 이것은 기본적으로 4 개의 선택을 반환합니다. 그 중 하나는 단지 하나의 행이므로 다른 3 개에 문제가있어 여기서 보여 드리겠습니다.
나는 시도했다 : 반복되는 ISNULL
절에
(select sum(importe) as importe
from Fact_Descuento (nolock) DD
where DD.IdComprobante = ci.idComprobante and ci.IdDim_Producto = IdDim_Producto
and ci.IdDim_Medida = IdDim_Medida and ci.IdDim_Calidad = IdDim_Calidad
and exists
(
select 1
from ComprobanteReferencias AA
inner join Fact_Comprobante BB on aa.IdComprobanteCredito = BB.IdComprobante
where AA.IdComprobanteDebito = DD.IdComprobante
and BB.IdDim_ComprobanteTipo in (4,13,16,19)
)
)
: 예를 들어, repetead 몇 가지 일을 해결하기 위해,이 하위 쿼리를 시도했다 내가 생각
3이 선택됩니다. 그래서, 나는 Common_Expresion_Table WITH을 사용하여 그것을 줄일 수 있다고 생각합니다. 하지만, 하위 쿼리를 사용할 때 하위 쿼리를 사용할 때 선택 항목의 값에 따라 선택 항목이 달라집니다 (하위 쿼리의 where
절에서 볼 수 있음)
그렇다면 3 개가 있습니다. 별로 다르지 않습니다. 그들은 조인을 몇 번 반복했지만 다른 방식으로 그룹화했습니다. 그래서, 나는 또한 시간적으로 테이블 또는 CTE의 어떤 종류를 사용하는 thougt,하지만 그들은 다른 방법에서 그룹화되어 있기 때문에 그것에 대해 확실하지 않다, 또한 하나 또는 두 개의 differents의 JOINS
일부 추가 정보가 있습니다
를#Seleccionados
에는 100 개의 ID 행이 있습니다. 이 쿼리에는 50 개의 seg가 필요합니다. 일주일의 경우 :
- 첫 번째 쿼리는 거의별로 그룹화 동일한 정보,의, 두 번째 질의는 당신이 볼 수있는 세 번째 쿼리가
47084 rows
반환 47084 rows
47083 rows
테이블 : Fact_Comprobante
한 판매에 대한 정보가 있습니다. Fact_ComprobanteItem
판매 항목에 대해. Dim_Producto
제품에 대한 정보, Dim_Familia
정보 제품군 Dim_Marca
은 Signs of products에 대한 정보를 가지고 있습니다. Dim_Linea
은 라인 제품에 대한 정보를 가지고 있습니다. (이 3 개의 테이블은 Dim_Producto에서 FK입니다.) Dim_ComprobanteTipo
판매 유형에 대한 정보를 얻었습니다 Fact_Descuento
판매에 관련된 할인 정보가 있습니다.
모든 테이블에는 많은 정보가 있습니다.
(Nolock)
진술은이 테이블에서 동시에 3 개의 서비스가 삽입, 업데이트 및 기타 서비스가 있기 때문입니다.
이 쿼리를 수행하지 않았으므로 최적화해야합니다.
답변을 주셔서 감사합니다! 나는 최근에 저장을 수정했고, 지금은 20segs 더 빠릅니다. 나는 첫 번째와 세 번째 sele ct를 입력 한 다음 다른 필드별로 그룹화를 선택하십시오. 나는 ISNULL 문을 수정해야한다는 것을 알고 있지만 어떻게해야할지 모르겠다. 바로 지금, 더 이상 돈이 없습니다 (예산은 미안 해요, 영어는 나쁜 것입니다). 그래서 나중에 보게 될 것입니다. –