Sql server 比较datetime和varchar的最有效方法

Sql server 比较datetime和varchar的最有效方法,sql-server,tsql,datetime,varchar,Sql Server,Tsql,Datetime,Varchar,我正在使用第三方Microsoft SQL Server数据库,其中大多数日期以yyyy\u MM\u dd hh:MM:ss.SSS格式保存为varchar列。在许多报告中,我需要选择由两个日期时间变量定义的特定时间范围。我使用以下语句: where cast(replace(a.somedate,'_','-') as datetime) between @begin and @end 我注意到,使用此语句,当需要处理大量记录时,查询很快就会变得昂贵。比较varchar和datetime最

我正在使用第三方Microsoft SQL Server数据库,其中大多数日期以
yyyy\u MM\u dd hh:MM:ss.SSS
格式保存为
varchar
列。在许多报告中,我需要选择由两个日期时间变量定义的特定时间范围。我使用以下语句:

where cast(replace(a.somedate,'_','-') as datetime) between @begin and @end

我注意到,使用此语句,当需要处理大量记录时,查询很快就会变得昂贵。比较varchar和datetime最有效的方法是什么?

由于这是一个供应商应用程序,您无法控制模式,因此您可以重构
WHERE子句,如下所示,以获得一个可搜索表达式。这将允许有效地使用
somedateas
上的索引。例如:

WHERE a.somedateas BETWEEN REPLACE(CONVERT(varchar(19), @begin, 120), '-', '_') AND REPLACE(CONVERT(varchar(19), @end, 120), '-', '_') 

您不能修复数据库以便正确存储日期吗?您如何创建一个持久化的计算字段?如果为数据库提供数据的系统仍在运行?在这种情况下,您可以为
@begin和@end
指定格式类似的varchar值。最好将模式固定为存储为
datetime
datetime2(0)
。要添加到@DanGuzman所说的内容中,如果在
somedate
上有索引,
其中somedate>='2000\u 01\u 01 00:00:00.000'和somedate<'2001\u 01\u 01 00:00.000'
应该给您一个索引查找,由ISO提供,日期可通过词汇顺序进行比较。如果没有索引,并且您无法添加索引,那么在这两个方向上优化操作都没有什么意义,因为比较不是瓶颈——扫描所有单独的行才是。如果您无法更改源,那么我建议与您的软件供应商支持团队谈谈,并与他们讨论。一个好的软件供应商应该知道如何正确地存储数据。谢谢,这就是我最后要做的。除了我使用varchar(23)获取整个datetime之外。