【发布时间】:2016-06-24 18:19:43
【问题描述】:
我有最新的 SQL 2012 标准版:
Microsoft SQL Server 2012 (SP3-CU3) (KB3152635) - 11.0.6537.0 (X64) 2016 年 4 月 28 日 17:57:34 版权所有 (c) Microsoft Corporation 标准 Windows NT 6.1(内部版本 7601:Service Pack 1)上的版本(64 位) (管理程序)
根据每个客户的用户数量的 2 个变量(月份和年份)进行简单计数,其中应用程序是特定的,行估计是实际结果的 10 倍。我已经释放了缓存,重建了索引,确保它正在执行索引搜索并尝试重新编译计划。如果我手动输入谓词,我会得到预期的结果和计划,但如果我使用 dateadd,我会得到一个夸张的版本,因为我在使用 CTE 的视图中有多个计数,我正在寻找一种方法来解决大量高估我认为 dateadd 导致的行。
SELECT
[Customer],
[Month],
[Year],
COUNT([Username]) AS 'RDS'
FROM [MS_CitrixUsers]
WHERE [Application] = 'RDS'
AND [Month] = DATENAME(month, dateadd(month, -1,GETDATE()))
AND [YEAR] = DATENAME(year, dateadd(month, -1,GETDATE()))
GROUP BY [MS_CitrixUsers].[Customer],
[MS_CitrixUsers].[Month],
[MS_CitrixUsers].[Year]
计数在包含膨胀行计数的排序之后触发流聚合。
我的观点是什么样的:
WITH RDS1
AS
(
SELECT
[Customer],
COUNT([Username]) AS 'RDS1'
FROM [MS_CitrixUsers]
WHERE [Application] = 'RDS'
AND [Month] = @month
AND [YEAR] = @year
GROUP BY [MS_CitrixUsers].[Customer],
[MS_CitrixUsers].[Month],
[MS_CitrixUsers].[Year]
),
RDS2
AS
(
SELECT
[Customer],
[Month],
[Year],
COUNT([Username]) AS 'RDS2'
FROM [MS_CitrixUsers]
WHERE [Application] = 'RDS'
AND [Month] = @monthbefore
AND [YEAR] = @year2
GROUP BY [MS_CitrixUsers].[Customer],
[MS_CitrixUsers].[Month],
[MS_CitrixUsers].[Year]
),
...
SELECT c.Customer,
CASE WHEN NOT EXISTS (SELECT [RDS1] FROM [RDS1] t1 WHERE t1.Customer = c.Customer)
AND EXISTS (SELECT [RDS2] FROM [RDS2] t2 WHERE t2.Customer = c.Customer) THEN '99999' ELSE ([RDS1] - Coalesce([RDS2], 0)) END AS 'RDS',
CASE WHEN NOT EXISTS (SELECT [CitrixUsage1] FROM [CitrixUsage] t1 WHERE t1.Customer = c.Customer)
AND EXISTS (SELECT [CitrixUsage2] FROM [CitrixUsage2] t2 WHERE t2.Customer = c.Customer) THEN '99999' ELSE ([CitrixUsage1] - Coalesce([CitrixUsage2], 0)) END AS 'Citrix Usage',
我得到的预期结果视图是 2 个月的数据之间的差异:
[客户] [应用程序1] ... [应用程序N]
客户1 -1 3
我们有很多应用程序,因此您可以想象返回结果需要相当长的时间,所以我看看优化估算是否会有所帮助。
解决方法:我发现在这里的另一个答案中,使用临时表,将我的变量粘贴在那里,然后加入我的表以避免流聚合,而是使用哈希匹配来估计正确的行数。
【问题讨论】:
-
你提到它是一个视图,你是在这个视图之外制作临时表吗?
-
仅在测试性能的解决方法中。我想我已经用尽了周围的一切:sqlperformance.com/2016/04/sql-performance/surprises-dateadd
标签: sql-server