我正在尝试降低我经常使用的查询的成本和大小,它看起来过于重复而不是最有效的处理方式。
简化表示如下:
SELECT [Year],
[Month],
COUNT(CASE WHEN Type = 'Quotation' THEN clientID ELSE NULL END),
COUNT(CASE WHEN Type = 'Purchase' THEN ClientID ELSE NULL END),
SUM(CASE WHEN Type = 'Purchase' THEN Cost ELSE NULL END)
...
FROM dbo.Example
GROUP BY [Year],[Month]
我认为我必须能够在尺寸和成本方面削减CASE WHEN ... THEN ELSE NULL END
。有什么建议吗?
我正在使用SQL Server 2008 R2,谢谢。
答案 0 :(得分:0)
按类型制作视图怎么样? (报价,购买等)。通过这种方式,您可以按视图优化视图并进行连接查询以获得所需内容。
答案 1 :(得分:0)
我认为这是“旋转”表格的推荐方法。
查看Microsoft的这篇文章 - > https://support.microsoft.com/en-us/kb/175574
可能费用在'类型'列中,也许你可以索引 - > How to create an index for a string column in sql?
答案 2 :(得分:0)
SELECT [Year],
[Month],
[Type],
COUNT(ClientID) "Count",
SUM(Cost) "TotalCost",
...
FROM dbo.Example
GROUP BY [Year],[Month],[Type]
你这样做的方法是对它进行去标准化。这就是性能如此糟糕的原因。当然,您在SUM(Cost)
时生成Type = 'Quotation'
,而您可能不需要,但添加通常不会影响查询效果。
是否有某些原因必须每个[Year],[Month]
只有一条记录?
答案 3 :(得分:0)
当你有一些复杂的东西,有很多条件聚合时,根据我的经验,如果你以逐步的方式构建它,它会更快更清晰。也就是说,拥有一个具有所需数据结构的表变量,并使用单个查询向其添加记录,避免使用CASE语句,并且(希望)根据索引列进行记录选择。
所以,如果你有一个名为@TypeTotals
的表变量,你可以这样做(使用简化的例子):
INSERT INTO @TypeTotals
SELECT [Year],
[Month],
[Type],
COUNT(ClientID),
Null,
Null
FROM dbo.Example
WHERE [Type] = 'Quotation'
GROUP BY
[Year], [Month]
INSERT INTO @TypeTotals
SELECT [Year],
[Month],
[Type],
Null,
COUNT(ClientID),
SUM(Cost)
FROM dbo.Example
WHERE [Type] = 'Purchase'
GROUP BY
[Year], [Month]
... etc ...
然后,您可以总结@TypeTotals
的内容。
速度的关键是避免那些CASE语句(正如你已经想到的那样)并使用你可以使用的索引。
并进行实验。如果可以,请使用Profiler,因为执行计划并不总是代表您真正获得的速度。