我正在研究新的存储过程并且所有内容都已设置,在代码审查期间我得到了注释以说明我不应该在联接中转换/转换而不是要求我将DateTime转换为int date然后比较这两个。< / p>
代码:
INNER JOIN SchedData SD
ON SD.EmployeeID = CAE.EmployeeID
AND CAST(CAST(SD.AssignDate AS VARCHAR(8)) AS DATETIME) BETWEEN @StartDate and @EndDate + 1
解释:
SD.AssignDate
属于20100801
@StartDate and @EndDate
是DateTime的参数。
当我在SQL论坛中在线搜索时,他们说它不会产生太多/任何差异,这就是我在评论中评论过的,但我只想重新确认SQL中众所周知的人,我正在使用MS Sql。
这里是关于在Sql论坛中播放的链接
请让我知道哪种方式可以使用。
如果有更好的方法,我很乐意实现该代码。
答案 0 :(得分:1)
当你施放一个场时,它通常会让它变得不可思议。 (仔细看看)。当它不可搜索时,它无法使用列AssignDate
上的索引(尽管我听说它在SQL的更高版本中越来越好)。如果您改为对参数进行转换,那么您不会对该字段进行转换,并且它变得可以使用索引,因此可以使用索引。
您发布的链接是关于在选择中投射的。这不是要在 join 或谓词列上进行转换,而这正是您在此处所做的。
例如,将代码更改为:
AND SD.AssignDate BETWEEN
CONVERT(INT,CONVERT(VARCHAR(8),@StartDate,112))
AND
CONVERT(INT,CONVERT(VARCHAR(8),@EndDate,112))
现在你没有一个字段周围的函数,如果它存在,它可以利用该列的索引......或者如果将来存在一个
我建议您使用CTRL-L来观察发生的事情并比较查询。
这是一些有趣的背景阅读,基本上说围绕列的一些函数都可以。
http://blogs.lobsterpot.com.au/2010/01/22/sargable-functions-in-sql-server/
答案 1 :(得分:0)
来自您自己的链接:
作为一般规则,对SELECT中的项目执行CAST或CONVERT 条款几乎没有成本。 (请注意,WHERE中的 CAST或CONVERT 或者ON子句可能非常昂贵,因为它们会保留SQL Server 从有效使用索引)。
最好的方法是,如果no.of行相当小,则将该列的数据类型转换为正确的Date或Datetime。
答案 2 :(得分:0)
据我所知和猜测
AND CAST(CAST(SD.AssignDate AS VARCHAR(8)) AS DATETIME) BETWEEN @StartDate and @EndDate + 1
应该是where子句的一部分而不是内部连接。
如果
SD.AssignDate
已经是一个日期时间字段,然后没有点将其转换为varchar,然后将其转换为日期时间。