如何优化以下查询:
SELECT CASE
WHEN COUNT(DISTINCT t1.[datecol]) = 0
THEN 0
ELSE SUM(CONVERT(FLOAT, Quantité)) / COUNT(DISTINCT t1.[datecol])
END AS QTEMOY,
CASE
WHEN COUNT(DISTINCT t1.[datecol]) = 0
THEN 0
ELSE SUM(CONVERT(FLOAT, [Prix de vente TTC])) / COUNT(DISTINCT t1.[datecol])
END AS CAMOY,
t1.[Code Article],
t1.[Code Structure],
t1.[Code Site]
FROM [Vente ] t1
OUTER APPLY (
SELECT DISTINCT TOP 28 t2.[datecol]
FROM [Vente ] t2
WHERE t2.[Code Article] = t1.[Code Article] AND t2.[Code Structure] = t1.[Code Structure] AND t2.[Code Site] = t1.[Code Site]
AND NOT EXISTS (
SELECT [Code Article]
FROM [Promotion ] a
WHERE t2.datecol BETWEEN [Date Debut Promo] AND [Date Fin Promo] AND t2.[Code Article] = a.[Code Article]
)
ORDER BY t2.[datecol] DESC
) t2
WHERE NOT EXISTS (SELECT t1.[Code Article] FROM [Promotion ] b WHERE t1.datecol BETWEEN [Date Debut Promo] AND [Date Fin Promo] AND t1.[Code Article] = b.[Code Article])
AND (t1.[Code Article] IS NOT NULL)
AND (t1.[Code Structure] IS NOT NULL)
AND (t1.[Prix de Revient] IS NOT NULL)
AND t1.datecol = t2.datecol
AND t1.[Code Article] IN (SELECT [Code Article] FROM [Reference] t)
GROUP BY t1.[Code Article],
t1.[Code Structure],
t1.[Code Site]
查询需要花费数小时才能优化它?
StmtText
|--Compute Scalar(DEFINE:([Expr1017]=CASE WHEN [Expr1014]=(0) THEN (0.000000000000000e+000) ELSE [Expr1015]/CONVERT_IMPLICIT(float(53),[Expr1014],0) END, [Expr1018]=CASE WHEN [Expr1014]=(0) THEN (0.000000000000000e+000) ELSE [Expr1016]/CONVERT_IMPLICIT(float(53),[Expr1014],0) END))
|--Compute Scalar(DEFINE:([t1].[Code Article]=[Expr1025], [t1].[Code Structure]=[Expr1026], [t1].[Code Site]=[Expr1027]))
|--Hash Match(Inner Join, HASH:([Expr1025], [Expr1026], [Expr1027])=([Expr1022], [Expr1023], [Expr1024]), RESIDUAL:([Expr1022] = [Expr1025] AND [Expr1023] = [Expr1026] AND [Expr1024] = [Expr1027]))
|--Compute Scalar(DEFINE:([Expr1025]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Article] as [t1].[Code Article], [Expr1026]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Structure] as [t1].[Code Structure], [Expr1027]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Site] as [t1].[Code Site]))
| |--Compute Scalar(DEFINE:([Expr1014]=CONVERT_IMPLICIT(int,[Expr1046],0)))
| |--Stream Aggregate(GROUP BY:([t1].[Code Article], [t1].[Code Structure], [t1].[Code Site]) DEFINE:([Expr1046]=Count(*)))
| |--Sort(DISTINCT ORDER BY:([t1].[Code Article] ASC, [t1].[Code Structure] ASC, [t1].[Code Site] ASC, [t1].[datecol] ASC))
| |--Table Spool
| |--Parallelism(Gather Streams)
| |--Filter(WHERE:([Expr1019]=[Expr1007]))
| |--Nested Loops(Left Outer Join, OUTER REFERENCES:([t1].[Code Site], [t1].[Code Article], [t1].[Code Structure]))
| |--Hash Match(Right Anti Semi Join, HASH:([b].[Code Article])=([t1].[Code Article]), RESIDUAL:([Expr1019]>=[QlikDataWarehouse].[dbo].[Promotion Geant].[Date Debut Promo] as [b].[Date Debut Promo] AND [Expr1019]<=[QlikDataWarehouse].[dbo].[Promotion Geant].[Date Fin Promo] as [b].[Date Fin Promo] AND [QlikDataWarehouse].[dbo].[Vente Geant].[Code Article] as [t1].[Code Article]=[QlikDataWarehouse].[dbo].[Promotion Geant].[Code Article] as [b].[Code Article]))
| | |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([b].[Code Article]))
| | | |--Index Scan(OBJECT:([QlikDataWarehouse].[dbo].[Promotion Geant].[id_date] AS [b]))
| | |--Compute Scalar(DEFINE:([Expr1019]=[QlikDataWarehouse].[dbo].[Vente Geant].[datecol] as [t1].[datecol], [Expr1020]=CONVERT(float(53),[QlikDataWarehouse].[dbo].[Vente Geant].[Quantité] as [t1].[Quantité],0), [Expr1021]=CONVERT(float(53),[QlikDataWarehouse].[dbo].[Vente Geant].[Prix de vente TTC] as [t1].[Prix de vente TTC],0)))
| | |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([t1].[Code Article]))
| | |--Nested Loops(Inner Join, OUTER REFERENCES:([t1].[ID], [Expr1045]) OPTIMIZED WITH UNORDERED PREFETCH)
| | |--Nested Loops(Inner Join, OUTER REFERENCES:([t].[Code Article], [Expr1044]) WITH UNORDERED PREFETCH)
| | | |--Stream Aggregate(GROUP BY:([t].[Code Article]))
| | | | |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([t].[Code Article]), ORDER BY:([t].[Code Article] ASC))
| | | | |--Index Scan(OBJECT:([QlikDataWarehouse].[dbo].[Reference].[Id_ref] AS [t]), ORDERED FORWARD)
| | | |--Index Seek(OBJECT:([QlikDataWarehouse].[dbo].[Vente Geant].[Id_SuiviRupture] AS [t1]), SEEK:([t1].[Code Article]=[QlikDataWarehouse].[dbo].[Reference].[Code Article] as [t].[Code Article] AND [t1].[Prix de Revient] IsNotNull), WHERE:([QlikDataWarehouse].[dbo].[Vente Geant].[Code Article] as [t1].[Code Article] IS NOT NULL AND [QlikDataWarehouse].[dbo].[Vente Geant].[Code Structure] as [t1].[Code Structure] IS NOT NULL) ORDERED FORWARD)
| | |--Clustered Index Seek(OBJECT:([QlikDataWarehouse].[dbo].[Vente Geant].[PK_Vente Geant] AS [t1]), SEEK:([t1].[ID]=[QlikDataWarehouse].[dbo].[Vente Geant].[ID] as [t1].[ID]) LOOKUP ORDERED FORWARD)
| |--Top(TOP EXPRESSION:((28)))
| |--Sort(DISTINCT ORDER BY:([Expr1007] DESC))
| |--Nested Loops(Left Anti Semi Join, WHERE:([Expr1007]>=[QlikDataWarehouse].[dbo].[Promotion Geant].[Date Debut Promo] as [a].[Date Debut Promo] AND [Expr1007]<=[QlikDataWarehouse].[dbo].[Promotion Geant].[Date Fin Promo] as [a].[Date Fin Promo]))
| |--Index Spool(SEEK:([t2].[Code Article]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Article] as [t1].[Code Article] AND [t2].[Code Structure]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Structure] as [t1].[Code Structure] AND [t2].[Code Site]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Site] as [t1].[Code Site]))
| | |--Compute Scalar(DEFINE:([Expr1007]=[QlikDataWarehouse].[dbo].[Vente Geant].[datecol] as [t2].[datecol]))
| | |--Index Scan(OBJECT:([QlikDataWarehouse].[dbo].[Vente Geant].[Id_SuiviRupture] AS [t2]))
| |--Clustered Index Seek(OBJECT:([QlikDataWarehouse].[dbo].[Promotion Geant].[PROMOG_CodeArtIndex] AS [a]), SEEK:([a].[Code Article]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Article] as [t1].[Code Article]) ORDERED FORWARD)
|--Compute Scalar(DEFINE:([Expr1022]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Article] as [t1].[Code Article], [Expr1023]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Structure] as [t1].[Code Structure], [Expr1024]=[QlikDataWarehouse].[dbo].[Vente Geant].[Code Site] as [t1].[Code Site]))
|--Compute Scalar(DEFINE:([Expr1015]=CASE WHEN [Expr1047]=(0) THEN NULL ELSE [Expr1048] END, [Expr1016]=CASE WHEN [Expr1049]=(0) THEN NULL ELSE [Expr1050] END))
|--Stream Aggregate(GROUP BY:([t1].[Code Article], [t1].[Code Structure], [t1].[Code Site]) DEFINE:([Expr1047]=COUNT_BIG([Expr1020]), [Expr1048]=SUM([Expr1020]), [Expr1049]=COUNT_BIG([Expr1021]), [Expr1050]=SUM([Expr1021])))
|--Sort(ORDER BY:([t1].[Code Article] ASC, [t1].[Code Structure] ASC, [t1].[Code Site] ASC))
|--Table Spool
答案 0 :(得分:0)
单独查看查询我可以看到一些性能问题:
使用OUTER APPLY和SELECT DISTINCT以及子查询。每个子查询都将作为嵌套循环操作执行,因此每个OUTER APPLY都会执行。这意味着需要进行多次额外操作 - 循环多次。
有很多子查询,导致1中定义的问题。