我有一个特殊的SQL查询似乎遇到了一个神秘的性能问题。这是查询:
SELECT COUNT(LengthOfTime) AS TotalTime,
SUM(LengthOfTime) AS TotalLength,
SUM(LengthOfTime) / COUNT(LengthOfTime) AS AverageTime,
SUM(Pops) / COUNT(LengthOfTime) AS AveragePop
FROM ((SELECT *
FROM (SELECT *, ID & YearRec AS ID2
FROM MyFirstTable
UNION ALL
SELECT *, ID & YearRec AS ID2
FROM Table2011) AS TEMP
WHERE STARTTIME >= '8/1/2011 00:00:00'
AND StartTime <= '8/5/2011 23:59:59' ) AS TEMP2
JOIN AppleTable ON TEMP2.Reason = AppleTable.Skills )
JOIN PeopleTable ON TEMP2.Operator = PeopleTable.Operators
WHERE AppleTable.[ON] = 1
AND PeopleTable.[ON] = 1
AND Rec_Type = 'SECRET AGENT'
这里的问题是,当运行5天时,此查询运行得非常快(0:00到0:02),但是在6天的跨度内非常慢(1:20到1:45)。
表格中每天约有105,000条记录(MyFirstTable和Table2011)。
我的问题 :在SQL Server中发现严重的性能问题之前,您可以传递聚合函数的行数是否有上限? (目前使用2008 R2)
答案 0 :(得分:9)
简短回答:不,没有一些神奇的记录会导致MSSQL开始表现不佳。
现在,可能的查询不能很好地扩展,因此,数据集越大,其执行的指数越大。
您将遇到的一个大问题是您在 UNIONED语句之后预测了StartTime 。相反,尝试在UNION之前的两个选择中预测它。这应该会产生巨大的差异,特别是如果你在StartTime上索引两个表(在这些表上生成索引)。
SELECT * FROM (
SELECT *, ID & YearRec AS ID2 FROM MyFirstTable
WHERE STARTTIME >= '8/1/2011 00:00:00'
AND STARTTIME <= '8/5/2011 23:59:59'
UNION ALL SELECT *, ID & YearRec AS ID2
FROM Table2011
WHERE STARTTIME >= '8/1/2011 00:00:00'
AND STARTTIME <= '8/5/2011 23:59:59'
) AS TEMP
您也可以对代码进行一些额外的重构。
答案 1 :(得分:4)
不,聚合函数没有预定义的上限。
性能偏差可能受以下一项或多项影响:
您可以在SSMS中运行查询并查看实际的执行计划。这将告诉您运行查询的成本最高的地方,这将帮助您确定最佳的行动方案。
根据评论进行修改:
如果Table2011
上没有包含[STARTTIME]
的索引,请创建一个。如果有一个索引,但它被忽略了,那么你必须找出原因。如果碎片化,那么重建索引肯定会有所帮助。以下是如何重建
ALTER INDEX [YourIndexName] ON [dbo].[Table2011] REBUILD WITH (STATISTICS_NORECOMPUTE = ON);
或者,您可以在SSMS中执行此操作 - 浏览到对象浏览器中的特定索引,右键单击并重建。