我有SQL Server代码,需要很长时间才能运行结果。在过去,花了15分钟。但最近,由于累积的销售数据,可能需要2个小时才能得到结果!!
因此,我想就如何优化代码获得一些建议:
代码结构很简单:只是为不同时间段和每个SKU获取不同地区的销售额。 (我在这里删除了一些代码,是为每种没有尺寸的材料找到不同的SKU)。
非常感谢您的帮助。
主要代码结构如下,因为它几乎相同,所以我只给出前两段作为例子:
SELECT SKU from [MATINFO]
-- Global Sales History Qty - All the years
LEFT JOIN
(
SELECT SKU,SUM([SALES Qty]) as [Global Sales History Qty - All the years]
from dbo.[SALES]
where [PO] IS NOT NULL
group by SKU
)histORy
on MATINFO.[SKU]=histORy.[SKU]
-- Global Sales History Qty - Past 2 years
LEFT JOIN
(
SELECT (
SELECT SKU,SUM([SALES Qty]) as [Global Sales History Qty - All the years]
from dbo.[SALES]
where [PO] IS NOT NULL
group by SKU
/* date range */
and ([ORDER DATE] = '2015.11' OR [ORDER DATE] = '2015.12' or [ORDER DATE] like '%2015%' OR [ORDER DATE] like '%2016%' )
group by SKU
)histORy2
on MATINFO.[SKU]=histORy2.[SKU]
--Global Sales History Qty - Past 1 years
......SIMILAR TO THE CODE STRUCTURE AS ABOVE

答案 0 :(得分:2)
性能不佳的最可能原因是使用字符串表示日期,如果是足够的索引则可能缺少。
喜欢'%2015%'
在全表扫描中使用具有相似结果的双端通配符,因此每次搜索不同的日期范围时子查询都会扫描整个表。使用临时表不能解决潜在的问题。
[稍后补充]
原始查询结构的另一个方面可能会减少您需要的数据扫描次数 - 使用“条件聚合”
e.g。这是原始查询的精简版
SELECT
SKU
FROM [MATINFO]
-- Global Sales History Qty - All the years
LEFT JOIN (SELECT
SKU
, SUM([SALES Qty]) AS [Global Sales History Qty - All the years]
FROM dbo.[SALES]
WHERE [PO] IS NOT NULL
GROUP BY
SKU) histORy ON MATINFO.[SKU] = histORy.[SKU]
-- Global Sales History Qty - Past 2 years
LEFT JOIN (SELECT
SKU
, SUM([SALES Qty]) AS [Global Sales History Qty - Past 2 years]
FROM dbo.[SALES]
WHERE [PO] IS NOT NULL
/* date range */
AND [ORDER DATE] >= '20151101' AND [ORDER DATE] < '20161101'
GROUP BY
SKU) histORy2 ON MATINFO.[SKU] = histORy2.[SKU]
这需要在dbo中进行2次完整的数据传递[SALES],但如果你在SUM()函数中使用case表达式,则只需要传递一次数据(在本例中)
SELECT
SKU
, SUM([SALES Qty]) AS [Qty_all_years]
, SUM(CASE
WHEN [ORDER DATE] >= '20151101' AND [ORDER DATE] < '20161101'
THEN [SALES Qty]
END) AS [Qty_past_2_years]
FROM dbo.[SALES]
WHERE [PO] IS NOT NULL
GROUP BY
SKU
我怀疑您可以将此逻辑应用于大多数列,并在与日期列和适当的索引配合使用时显着提高查询效率。
答案 1 :(得分:1)
扩展我的评论。请注意,这只是一个建议,如果运行得更快,则无法保证。
采用以下派生表histORy
:
SELECT SKU,SUM([SALES Qty]) AS [Global Sales History Qty - All the years]
FROM dbo.[SALES]
WHERE [PO] IS NOT NULL
GROUP BY SKU
在运行查询之前,在临时表中实现派生表:
SELECT SKU,SUM([SALES Qty]) AS [Global Sales History Qty - All the years]
INTO #histORy
FROM dbo.[SALES]
WHERE [PO] IS NOT NULL
GROUP BY SKU
然后在查询中使用临时表:
LEFT JOIN #histORy AS h ON MATINFO.[SKU]=h.[SKU]
在这种情况下,您可能希望在SKU
字段上有一个索引,因此您可以自己创建临时表,在其上打一个索引,填充INSERT INTO #history... SELECT ...
等。