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

rlb*_*usa 4 sql datediff query-optimization

我正在尝试优化一些非常复杂的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 
Run Code Online (Sandbox Code Playgroud)

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

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

Ada*_*Dev 13

这取决于你正在做什么,说实话的性能程度.

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

例如基本示例,查找2009年的所有记录

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0
Run Code Online (Sandbox Code Playgroud)

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

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'
Run Code Online (Sandbox Code Playgroud)

如果你感兴趣的话,我最近在博客上写了这个差异(与性能统计/执行计划比较).

这比将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
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助.

  • 正确,当然这适用于几乎*任何用于包装索引列的函数,而不仅仅是`DATEDIFF`. (2认同)