Точность SQL Getdate? - PullRequest
       32

Точность SQL Getdate?

3 голосов
/ 01 августа 2010

Я экспериментирую с программой, которая с высокой скоростью вставляет данные в базу данных SQL 2005 Server (в XP SP3). (Это для сбора данных о времени, чтобы я мог оценить различные аспекты моего дизайна).

Моя базовая установка включает в себя вставку данных в таблицу, как показано ниже (и использование SP, который просто определяет поле полезной нагрузки):

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

Обратите внимание, что оба поля даты и времени также имеют уникальные ограничения.

В клиентской программе я вызывал SP в такой тесной петле, что у меня возникли проблемы с точностью значения .Net DateTime.Now (и, возможно, также спящего потока) и, следовательно, нарушение уникального ограничения полезной нагрузки. Я обратился с помощью комбинации переменной секундомера, небольшого количества Thread.Sleep () и ручного построения данных «полезной нагрузки», чтобы они не нарушали разрешение поля SQL DateTime (3,3 мс)

Однако, когда вставки генерируются со скоростью от 5 мс до 10 мс, я начал видеть проблемы с полем «Вставка» на стороне SQL, где строка регулярно отклоняется из-за нарушения уникального ключа. Только когда я замедляю скорость вставки более чем до 15 мс, эта проблема исчезает. Эта скорость подозрительно похожа на проблему точности, с которой я столкнулся в .Net DateTime.Now (где-то я прочитал 16 мс), поэтому мне интересно, какова действительная точность функции SQL Getdate ().

Так может кто-нибудь сказать мне, что поддерживает GetDate (), и будет ли он привязан к тому же источнику, что и значение .Net DateTime.Now? И какой точности от этого ожидать?

Кроме того, я знаю о типе DATETIME2 на сервере SQL 2008, поэтому возникает вопрос о том, какова точность для GetDate () в этой системе.

Ответы [ 2 ]

2 голосов
/ 01 августа 2010

DATETIME имеет точность 3,3 мс, но GETDATE () не возвращает точное время, как вы обнаружили. Посетите страницу MSDN для типов / функций даты / времени для получения дополнительной информации о том, как работают новые типы / функции.

1 голос
/ 01 августа 2010

DATETIME хранится как 2 целых числа. Один, представляющий часть даты, а другой - часть времени (количество тактов после полуночи), каждый такт равен 1/300 секунды , поэтому теоретическая точность составляет 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

Что касается вашего запроса о точности GetDate() в SQL Server 2008, он такой же, как и для 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
...