sysdatetime返回datetime2(7)(精度100纳秒),getdate返回datetime(精度3.33毫秒),二者类型与精度本质不同;要真正利用高精度,必须统一使用datetime2类型,否则隐式转换会导致截断或错误。

SYSDATETIME 返回的是 datetime2(7),精度达 100 纳秒;GETDATE 返回 datetime,精度仅 3.33 毫秒 —— 这不是“更高精度”的问题,而是类型和底层精度的根本差异。
SYSDATETIME 和 GETDATE 的返回类型不同
这是最常被忽略的前提。你不能简单“替换函数”就获得更高精度,因为结果类型变了,下游逻辑可能出错:
-
GETDATE()返回datetime(范围:1753–9999,精度:3.33ms) -
SYSDATETIME()返回datetime2(7)(范围:0001–9999,精度:100ns) - 直接在旧表字段为
datetime的列上插入SYSDATETIME()值,会隐式截断精度,且可能触发警告(如 SET ARITHABORT ON 时) - 比较时若混用两者(如
WHERE dt > GETDATE()vsWHERE dt > SYSDATETIME()),实际精度不一致,但语义上可能被误认为“更准”
想真正利用高精度,必须显式声明 datetime2 类型
否则你只是拿到了一个高精度值,然后立刻被 cast 或 truncation 吃掉:
- 建表时用
datetime2(3)或datetime2(7)替代datetime字段 - 变量声明必须匹配:
DECLARE @t DATETIME2(7) = SYSDATETIME();,而非DECLARE @t DATETIME = SYSDATETIME();(后者会丢失精度) - INSERT/UPDATE 时避免隐式转换:确保目标列是
datetime2,或显式CONVERT(DATETIME2(7), SYSDATETIME()) - 注意 ORM(如 Entity Framework)默认映射
datetime,需手动配置属性为[Column(TypeName = "datetime2")]
精度提升对性能和存储有实际影响
不是“越高越好”,得看场景:
-
datetime2(0)占 6 字节,datetime2(7)占 8 字节,datetime占 8 字节 —— 看似一样,但索引键变宽会影响 B-Tree 深度 - 高精度时间戳在日志、审计、分布式事务排序中有价值;但在订单创建时间这种人工感知不到毫秒级差异的场景,用
datetime2(3)足够,省空间也减少序列化开销 - 跨 SQL Server 版本要注意:
datetime2在 SQL Server 2008+ 支持,2005 及更早不识别,会报错Incorrect syntax near 'datetime2'
常见错误:以为 SYSDATETIME() 就能解决时区或同步问题
它只返回本地服务器时间(无时区信息),和 GETDATE() 一样:
- 需要带时区?用
SYSDATETIMEOFFSET(),返回datetimeoffset类型 - 需要 UTC 时间?用
GETUTCDATE()(精度低)或SYSUTCDATETIME()(精度高,返回datetime2(7)) - 集群中多节点时间不同步?
SYSDATETIME()不解决 NTP 偏差,得靠运维校时,函数本身无法补偿
真正用好 SYSDATETIME() 的关键,不是换函数,而是确认你的列类型、变量类型、应用层映射、业务对精度的真实需求是否全部对齐。漏掉任意一环,所谓“更高精度”只是幻觉。











