我支持另一位开发人员编写的现有应用程序,我有一个问题,即开发人员选择存储日期的数据类型是否会影响某些查询的性能。
相关信息:该应用程序大量使用其中一个表中的“业务日期”字段。此业务日期的数据类型是nvarchar(10)而不是日期时间数据类型。日期格式为“MM / DD / YYYY”,因此2007年圣诞节存储为“12/25/2007”。
长话短说,我们有一些重要的查询,每周运行一次,并且需要很长时间才能执行。
我正在重新编写这个应用程序,但是因为我正在研究这个,我想知道使用datetime数据类型与存储日期之间是否存在性能差异。当前数据库。
答案 0 :(得分:6)
如果使用datetime而不是nvarchar(10),则可以节省磁盘空间并提高性能。
如果使用日期字段进行日期计算( DATEADD 等),您会看到查询执行速度大幅提升,因为字段不需要转换为日期时间在运行时。
答案 1 :(得分:3)
DATETIME
以上的操作比VARCHAR
转换为DATETIME
的速度快。
如果您的日期出现在SELECT
子句中的任何位置(例如,您添加它们,DATEDIFF
它们,在WHERE
子句等中搜索它们,那么您应该将它们保留在内部格式。
答案 2 :(得分:0)
有很多原因你应该使用DateTime而不是varchar来存储日期。性能是一个...但我会担心这样的查询:
SELECT *
FROM Table
WHERE DateField > '12/25/2007'
给你错误的结果。
答案 3 :(得分:0)
我不能用数字来支持它,但是datetime类型应该快得多,因为它可以很容易地进行比较,与varchar不同。在我看来,将UNIX时间戳作为数据类型进行研究也是值得的。
答案 4 :(得分:0)
是。 datetime对于日期计算来说比varchar或nvarchar更有效(为什么nvarchar - 你不可能在那里得到真正的unicode,对吧?)。加上字符串可能无效并被误解。
如果您只使用日期部分,则系统可能具有较小的日期时间版本。
此外,如果您只是进行连接和某些类型的操作(>/</=
比较但不是datediff),则日期“id”列实际上是yyyymmdd形式的int,通常用于数据仓库中。不幸的是,这确实允许“无效”日期,但它也允许更明显保留,“特殊”日期,而在日期时间,您可以使用1/1/1900的NULL
或一些东西。完整性通常通过对日期“维度”的密钥约束来强制执行。
看到您将问题标记为“sql server”,我假设您使用的是某个版本的SQL Server,因此我建议您使用datetime
或smalldatetime
查看。此外,在SQL Server 2008中,您有date
类型以及范围更大的datetime2
。查看this link,其中提供了一些详细信息
答案 5 :(得分:0)
我相信从架构的角度来看,Datetime是一种更有效的数据类型,因为它将存储为两个4字节的整数,而你的nvarchar(10)将存储为最多22个字节(数字的两倍)输入的字符数+ 2个字节。)。因此,与使用Datetime相比,现在可能需要的存储空间量增加一倍以上。
这当然会对索引产生影响,因为数据项越小,索引数据页面上的记录就越多。这反过来会产生一个较小的索引,当然可以更快地遍历,因此可以更快地返回结果。
总之,日期时间是最佳选择。
答案 6 :(得分:0)
有可能日期时间类型更紧凑,更快,但更重要的是使用DATETIMES存储日期和时间是更好的架构选择。你不太可能遇到奇怪的问题,寻找特定日期范围之间的记录,大多数数据库库会将它们映射到你的语言日期类型,所以代码更清晰,从长远来看这更为重要。 / p>
即使速度较慢,您也会花费更多时间来调试字符串作为日期,而不是所有用户在节省的费用中看到的。
答案 7 :(得分:0)
nvarchar字段中的日期过滤并不容易,因为索引中的数据按字典顺序排序,与日期的排序不匹配。这是日期格式“mm / dd / yyyy”的问题。这意味着“12/25/2007”将在nvarchar索引中的“12/01/2008”之后,但这不是你想要的。 “yyyy / mm / dd”本来没问题。
因此,您应该使用日期字段并将字符串值转换为日期。你肯定会获得巨大的性能提升。那就是你可以改变表模式。
答案 8 :(得分:0)
使用varchar(或任何其他字符串数据类型)的另一个问题是数据可能包含无效日期,因为它们在输入时不会自动验证。如果您尝试将该字段更改为日期时间字段,您可能会在人们添加日期(如ASAP,未知,2009年1月32日等)时出现转换问题。您需要检查不会使用该日期转换的日期方便的isdate函数,在尝试修改数据类型之前修复或将其清空。
可能你也有很多代码可以动态地将varchar类型转换为date数据类型,这样你也可以进行日期数学运算。所有代码也需要修复。