【问题标题】:Precision of SQL Getdate?SQL Getdate 的精度?
【发布时间】:2010-07-31 23:00:23
【问题描述】:

我正在试验一个以高速将数据插入 SQL 2005 Server 数据库(在 XP SP3 上)的程序。 (这是为了收集时序数据,以便我可以评估我设计的不同方面)。

我的基本设置包括将数据插入到如下表中(并使用仅指定有效负载字段的 SP):

create table data
(
 Id int  PRIMARY KEY Identity,
 payload datatime not null,
 inserted datetime default (getdate()) not null
)

请注意,两个日期时间字段也都具有 UNIQUE 约束。

在客户端程序上,我在如此紧密的循环中调用 SP,以至于我遇到了 .Net DateTime.Now 值的精度问题(也可能是线程休眠),因此违反了有效负载的唯一约束。我通过一个秒表变量、一点 Thread.Sleep() 和手动构建“有效负载”数据的组合来解决,这样它就不会违反 SQL DateTime 字段的分辨率 (3.3 mS)

但是,随着插入的生成速度介于 5 毫秒和 10 毫秒之间,我开始看到 SQL 端的“已插入”字段存在问题,其中一行因唯一键违规而定期被拒绝。只有当我将插入速率降低到超过 15 毫秒左右时,这个问题才会消失。这个速度有点像我在.Net DateTime.Now 中遇到的精度问题(我在某处的帖子上读到 16mS)所以我想知道 SQL Getdate() 函数的实际精度是多少。

那么有人可以告诉我支持 GetDate() 的是什么,它会与 .Net DateTime.Now 值绑定到相同的源吗?我应该期望它达到什么样的精度?

顺便说一句,我知道 SQL 2008 服务器中的 DATETIME2 类型,因此提出了一个问题,即该系统中 GetDate() 的精度是多少。

【问题讨论】:

  • 为什么需要对插入的列进行唯一约束?身份列将显示它们被插入的顺序。我认为数据库生成时间很容易受到由于并发活动,它可以处理您的插入请求的频率的自然变化的影响,之前的插入是否导致页面拆分等无论如何,所以不能真正具有任何语义含义保证像那样限制它。
  • @martin .. 唯一性和顺序不是一回事。我正在尝试不能同时插入两行的想法——但是 getdate 的精度证明我错了。但是我并不是说我正在做的是世界上最聪明的事情!

标签: sql-server-2005 precision getdate


【解决方案1】:

DATETIME 的精度为 3.3 毫秒,但 GETDATE() 不会像您发现的那样返回精确到此的时间。查看MSDN page for date/time types/functions 了解有关新类型/功能如何工作的更多信息。

【讨论】:

  • 我不同意术语。分辨率是3.3mS,但精度不是!而且我看到了那个页面,其中包含关键语句“所有系统日期和时间值都来自运行 SQL Server 实例的计算机的操作系统”。这并没有说明它们是如何派生的!
  • DATETIME 的精度为 3.3 毫秒(或大约) - 如果您从原子钟设置它,则精确到 3.3 毫秒。 :) 这里的问题是 GETDATE(),而不是 DATETIME。分辨率是一个更好的术语。
  • 。鉴于 getdate 返回一个日期时间,它们有点交织在一起.. 但是是的,我知道 GetDate 是这里的问题.. 还请查看tutelman.com/golf/measure/precision.php
【解决方案2】:

DATETIME 存储为 2 个整数。一个代表日期部分,另一个代表时间部分(午夜后的滴答数)每个滴答 is 1/300 of a second 所以它的理论精度至少为 3.3 毫秒。

我刚刚尝试在我的机器上运行它

declare @d  varchar(24)

while 1=1 
begin
set @d=CONVERT(VARCHAR(24), GETDATE(), 113)
raiserror('%s',0,1, @d) with nowait
end

并且运行时间相当长,一次只上升一个刻度,所以我认为不会有任何固有的限制阻止它实现这一目标。

01 Aug 2010 00:56:53:913
...
01 Aug 2010 00:56:53:913
01 Aug 2010 00:56:53:917
...
01 Aug 2010 00:56:53:917
01 Aug 2010 00:56:53:920
...
01 Aug 2010 00:56:53:920
01 Aug 2010 00:56:53:923

关于 SQL Server 2008 中关于 GetDate() 精度的查询,这与 SQL2005 相同。 sysdatetime 意味着具有更高的精度。我刚刚尝试运行以下命令,并对两个结果之间的差异感到惊讶。

SET NOCOUNT ON

CREATE TABLE #DT2(
[D1] [datetime2](7) DEFAULT (getdate()),    
[D2] [datetime2](7) DEFAULT (sysdatetime())
) 
GO

INSERT INTO #DT2
          DEFAULT  VALUES
GO 100

SELECT DISTINCT [D1],[D2],DATEDIFF(MICROSECOND, [D1], [D2]) AS MS
 FROM #DT2

结果

D1                           D2                              MS
----------------------------    -----------------------      ------
2010-08-01 18:45:26.0570000   2010-08-01 18:45:26.0625000     5500
2010-08-01 18:45:26.0600000   2010-08-01 18:45:26.0625000     2500
2010-08-01 18:45:26.0630000   2010-08-01 18:45:26.0625000     -500
2010-08-01 18:45:26.0630000   2010-08-01 18:45:26.0781250     15125
2010-08-01 18:45:26.0670000   2010-08-01 18:45:26.0781250     11125
2010-08-01 18:45:26.0700000   2010-08-01 18:45:26.0781250     8125

【讨论】:

  • 这种差异并非不合理,因为在将数据插入表时计时器不会停止。我在msdn.microsoft.com/en-us/library/ms188383.aspx MS 页面上看到他们在演示 "select Getdate(), sysdatetime()" 时提到了这一点。然而,我的问题似乎围绕着我的机器上的 getdate() 仅返回粒度约为 15 毫秒的日期时间值。我稍后会运行您的查询,看看它们在我的机器上弹出什么。顺便说一句,您正在运行什么硬件和操作系统?
  • 我刚刚又看了一下你的结果,看起来在插入过程中一定发生了一些奇怪的事情,我可以在单行上处理 D1 != D2,但是所有这些 D2 值都更大比几个不同行上的 D1 值真的很有趣(或可怕)。一定是某种奇怪的线程问题
  • @Peter - RE:我的台式机上的规格,所以 XP,2GB RAM 可能会加载来自其他应用程序的并发活动,但 GetDate 版本如何没有得到仍然没有意义到26.07 直到 sysdatetime 报告 26.078 之后。每个插入都在自己的事务中,因此应该在开始下一个事务之前提交。
猜你喜欢
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 2014-09-24
  • 1970-01-01
  • 2012-06-23
相关资源
最近更新 更多