转换SQL server datetime字段以仅比较日期部分,并使用索引查找

Cav*_*rob 28 datetime sql-server-2005

我一直convert(varchar,datefield,112)在每个日期字段上执行一次我在SQL服务器中的'之间'查询中使用,以确保我只根据日期时间字段的时间部分计算日期而不会丢失任何日期.

现在,我听说转换器不可索引,并且在SQL Server 2005中有更好的方法来比较查询中日期时间的日期部分,以确定日期是否属于某个范围.

做这样的事情的最佳,可索引的方法是什么:

select * from appointments
where appointmentDate>='08-01-2008' and appointmentDate<'08-15-2008'
Run Code Online (Sandbox Code Playgroud)

Cha*_*ana 67

剥离日期时间字段的时间部分的最佳方法是使用datediff和dateadd函数.

   DateAdd(day, datediff(day,0, MydateValue), 0)
Run Code Online (Sandbox Code Playgroud)

这有利于SQL Server将日期存储为两个整数这一事实,一个表示自"0"日起的天数 - (1月19日),第二个表示刻度数(每个刻度约为3.33 ms) )自午夜(当时)*.

上面的公式只需要读取第一个整数.不需要转换或处理,因此速度非常快.

要使查询使用索引...首先在输入过滤参数上使用此公式,或在表日期时间字段的等号的"其他"侧使用此公式,以便查询优化器不必运行计算在表中的每个datetime字段上,以确定哪些行满足过滤谓词.这使您的搜索参数"SARG-able"(搜索ARGument)

Where MyDateTimeColumn > DateAdd(day, 
      datediff(day,0, @MydateParameter), 0)    -- SARG-able
Run Code Online (Sandbox Code Playgroud)

而不是

Where DateAdd(day, datediff(day,0, 
      MyDateTimeColumn ), 0) > @MydateParameter -- Not SARG-able
Run Code Online (Sandbox Code Playgroud)

*注意.在内部,第二个整数(时间部分)存储刻度.在一天中有24 x 60 X 60 X 300 = 25,920,000个刻度(偶然地在最大值之下,32位整数可以保持).但是,在算术修改日期时间时,您无需担心这一点...当从日期时间添加或减去值时,您可以将该值视为分数,就好像它完全等于一天的小数部分一样,就好像完整日期时间值是一个浮点数,由表示日期的整数部分和表示时间的小数部分组成.即

`Declare @Dt DateTime  Set @Dt = getdate()  
 Set @Dt = @Dt + 1.0/24  -- Adds one hour  
 Select @Dt  
 Set @Dt = @Dt - .25 -- Moves back 6 hours  
 Select @Dt`
Run Code Online (Sandbox Code Playgroud)


Sti*_*ack 5

将数字类型转换为字符串值(一种Boxing)并不是执行所需操作的最佳方法.它实际上不是关于索引的,因为实际的列类型是日期时间.

如果您正在寻找日期的最佳查询方式,那么您的示例是正确的,但您可能需要考虑MSSQL中3 ms的精度差异.这可能意味着一天的记录可以显示在另一天的结果中.

这个

select * from appointments where appointmentDate>='08-01-2008' and appointmentDate<'08-15-2008'
Run Code Online (Sandbox Code Playgroud)

应该是这个

select * from appointments where appointmentDate>='08-01-2008' and appointmentDate<='08-14-2008 23:59:59.996'
Run Code Online (Sandbox Code Playgroud)

  • 这里的最后一点不是好建议.使用<=和.997值会导致某些人出现问题,因为它依赖于日期时间数据类型的解析.如果表已更改为smalldatetime,datetime2或date,则查询将中断.使用正确的符号> = AND <仍将适用于任何这些更改. (3认同)