SQL DATEDIFF(年,......,......)是一项昂贵的计算吗?

时间:2010-03-30 17:41:59

标签: sql query-optimization datediff

我正在尝试优化一些非常复杂的SQL查询,因为它需要很长时间才能完成。

在我的查询中,我动态创建了具有许多相同函数的SQL语句,因此我创建了一个临时表,其中每个函数只调用一次而不是多次 - 这使我的执行时间缩短了3/4。

所以我的问题是,如果说1000个日期计算的范围缩小到100,我可以期待看到很多不同吗?

编辑: 查询如下所示:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID 
WHERE ( #TEMP.Property1=1 ) AND 
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17 

这些是作为字符串动态生成的(按位组合在一起),然后执行,以便可以在每次迭代时更改各种参数 - 主要是最后一行,包含各种DATEDIFF查询。

这样的约有420个查询,这些日期计算就像这样计算。我知道我可以轻松地将它们全部放入临时表(1000个日期变为50) - 但它是否值得,它会在几秒钟内产生任何差异吗?我希望能比十分之一秒更好地改善。

3 个答案:

答案 0 :(得分:13)

这取决于你所做的事情,说实话的程度。

例如,如果您在WHERE子句中使用DATEDIFF(或实际上任何其他函数),那么这将导致性能较差,因为它会阻止在该列上使用索引。

e.g。基本示例,查找2009年的所有记录

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

不会很好地利用DateColumn上的索引。鉴于更好的解决方案,提供最佳索引使用将是:

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

recently blogged关于它的差异(与性能统计/执行计划比较),如果你感兴趣的话。

这比将DATEDIFF作为结果集中的列返回要花费更多。

我首先要确定花费最多时间的各个查询。检查执行计划以查看问题所在并从那里调整。

修改 根据您给出的示例查询,您可以尝试在WHERE子句中删除DATEDIFF的使用。找到在给定日期10岁的每个人的基本示例 - 我认为数学是正确的,但无论如何你都会得到这个想法!给它一个快速测试,似乎很好。应该很容易适应你的场景。如果你想找到某个日期(例如)15到17岁之间的人,那么这种方法也是可以的。

-- Assuming @Date2 is set to the date at which you want to calculate someone's age 
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10  

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, -@AgeAtDate , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

一个重要的补充说明,就是来自DOB的年龄计算,这种方法更准确。您当前的实施仅考虑出生年份,而不是实际的一天(例如,2009年12月1日出生的人将在2010年1月1日出现1岁时,直到2010年12月1日他们不是1岁)。

希望这有帮助。

答案 1 :(得分:0)

与其他处理日期时间值的方法(如字符串)相比,DATEDIFF非常有效。 (see this SO answer)。

在这种情况下,听起来你会翻阅相同的数据,这可能比使用临时表更昂贵。例如,将生成统计信息。

答案 2 :(得分:0)

您可能能够提高性能的一件事可能是在MID上的临时表上放置一个索引。

检查执行计划以查看它是否有帮助(可能取决于临时表中的行数)。