2010-07-31 75 views
3

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

我的基本设置涉及数据插入到像表中的下列(和使用,只是指定的有效载荷字段中的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)。

但是,插件的生成速度在5mS和10mS之间我已经开始发现SQL定义的“Inserted”字段存在问题,在这个字段中,针对唯一的键违规行定期被拒绝。只有当我的插入速度放慢到超过15毫秒时,这个问题才会消失。这个速度与我使用.Net DateTime.Now(我在某个帖子上读取16mS)的精度问题相似,所以我想知道SQL Getdate()函数的实际精度是多少。

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

另一方面,我知道SQL 2008服务器中的DATETIME2类型,因此引发了该系统中GetDate()的精度问题。

+0

为什么在插入的列上需要唯一的约束?身份列将显示他们插入的顺序。我认为数据库生成的时间很容易受到由于并发活动而导致的插入请求处理频率的自然变化,无论前一个插入是否导致页面拆分等,无论如何都不能具有任何语义含义保证像这样限制它。 – 2010-07-31 23:36:44

+0

@马丁..唯一性和顺序不是一回事。我一直在想,你不能同时插入两行 - 但getdate的精度已经证明我错了。但我并不是说我正在做的是世界上最聪明的事情! – 2010-07-31 23:41:54

回答

1

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 
+0

这些差异并非不合理,因为定时器在数据插入表格时并不会停止。我在这个http://msdn.microsoft.com/en-us/library/ms188383.aspx MS页面上看到他们在演示“选择Getdate(),sysdatetime()”时提到了这一点。然而,我的问题似乎围绕我的机器上的getdate(),只返回约15毫秒粒度的日期时间值。稍后我将运行您的查询并查看他们在我的计算机上弹出的内容。顺便说一句,你在运行什么硬件和操作系统? – 2010-08-01 19:50:13

+0

我只是再看看你的结果,看起来在插入过程中必定会出现一些奇怪的事情,我可以在单行上处理D1!= D2,但是在所有这些D2值都大于D1值时行真的很有趣(或可怕)。必须是某种奇怪的线程问题 – 2010-08-01 19:56:12

+0

@Peter - RE:规格刚好在我的台式机上,所以XP,2GB内存可能会从其他应用程序中并发活动,但它仍然没有意义,GetDate版本没有意义在sysdatetime报告26.078之后直到26.07。每个插入都在它自己的事务中,所以在启动下一个插入之前应该已经提交。 – 2010-08-01 21:59:42

2

DATETIME拥有3.3ms的精度,但GETDATE()如你发现没有返回时间精确到这一点。查看MSDN page for date/time types/functions了解更多关于新类型/函数如何工作的信息。

+1

我会不同意术语。分辨率是3.3mS,但精度不是!我已经看到那个包含关键句子的页面“所有系统日期和时间值都是从运行SQL Server实例的计算机的操作系统派生而来的。”没有说明它们是如何派生的! – 2010-07-31 23:38:53

+0

DATETIME的精确度为3.3ms(或其附近) - 如果您已经从原子钟设置它,则精确到3.3ms。 :)它是GETDATE()这里是问题,而不是DATETIME。分辨率是一个更好的词,寿'。 – 2010-07-31 23:43:22

+0

。鉴于getdate返回一个日期时间,他们是交织在一起..但是,我知道GetDate是这里的问题..也检查出http://www.tutelman.com/golf/measure/precision.php – 2010-07-31 23:46:01