sql-server SQL Server의 DateTime2와 DateTime 비교





7 Answers

DATETIME2 은 "0001 / 01 / 01"에서 "9999 / 12 / 31"까지의 날짜 범위를 가지며 DATETIME 유형은 1753-9999 만 지원합니다.

또한 필요한 경우 DATETIME2 는 시간면에서보다 정확할 수 있습니다. DATETIME은 3 1/3 밀리 초로 제한되며 DATETIME2는 100ns까지 정확합니다.

두 형식 모두 .NET의 System.DateTime 에 매핑됩니다. 차이는 없습니다.

선택의 여지가 있다면 가능할 때마다 DATETIME2 사용하는 것이 좋습니다. DATETIME (역 호환성을 제외하고)을 사용하면 어떤 이점도 보이지 않습니다. 날짜가 범위를 벗어나 번거롭기 때문에 문제가 덜 생깁니다.

더하기 : 날짜 만 필요하면 (시간 부분없이) DATE를 사용하십시오. DATETIME2 만큼 좋으며 공간도 절약 할 수 있습니다! :-) 같은 시간에만갑니다 - TIME 사용하십시오. 이것이 바로 이러한 유형의 요소입니다!

sql sql-server tsql datetime datetime2

어느 것:

SQL Server 2008 이상에서 날짜 및 시간을 저장하는 가장 좋은 방법은 무엇입니까?

정확도 (및 저장 공간이 아마도 차이가 있음)를 알고 있지만, 지금은 무시하고, 무엇을 사용해야하는지 또는 datetime2 만을 사용해야하는지에 대한 모범 사례 문서가 있습니까?




@marc_s 및 @Adam_Poward와 동의합니다 - DateTime2는 앞으로 나아갈 기본 방법입니다. 날짜 범위가 더 넓고 정확도가 높으며 저장량이 같거나 적게 사용됩니다 (정밀도에 따라 다름).

그러나 토론이 놓친 한 가지 ...
@Marc_s states : Both types map to System.DateTime in .NET - no difference there . Both types map to System.DateTime in .NET - no difference there . 이것은 맞지만 역변환은 사실이 아닙니다 ... 날짜 범위 검색을 수행 할 때 중요합니다 (예 : "2010 년 5 월 5 일에 수정 된 모든 레코드 찾기").

Datetime 의 .NET 버전은 DateTime2 와 비슷한 범위와 정밀도 DateTime2 집니다. .net Datetime 을 이전 SQL DateTime 매핑 할 때 암시 적 반올림이 발생합니다 . 이전 SQL DateTime 은 3 밀리 초까지 정확합니다. 즉, 11:59:59.997 은 하루가 끝날 때까지 가능한 한 가깝습니다. 더 높은 것은 다음 날까지 반올림됩니다.

이 시도 :

declare @d1 datetime   = '5/5/2010 23:59:59.999'
declare @d2 datetime2  = '5/5/2010 23:59:59.999'
declare @d3 datetime   = '5/5/2010 23:59:59.997'
select @d1 as 'IAmMay6BecauseOfRounding', @d2 'May5', @d3 'StillMay5Because2msEarlier'

이 암시적인 반올림을 피하는 것이 DateTime2로 이동할 중요한 이유입니다. 암시 적으로 날짜를 반올림하면 분명히 혼동을 일으킬 수 있습니다.




다음은 smalldatetime, datetime, datetime2 (0) 및 datetime2 (7) 사이의 저장소 크기 (바이트)와 정밀도의 차이를 보여주는 예제입니다.

DECLARE @temp TABLE (
    sdt smalldatetime,
    dt datetime,
    dt20 datetime2(0),
    dt27 datetime2(7)
)

INSERT @temp
SELECT getdate(),getdate(),getdate(),getdate()

SELECT sdt,DATALENGTH(sdt) as sdt_bytes,
    dt,DATALENGTH(dt) as dt_bytes,
    dt20,DATALENGTH(dt20) as dt20_bytes,
    dt27, DATALENGTH(dt27) as dt27_bytes FROM @temp

돌아 오는

sdt                  sdt_bytes  dt                       dt_bytes  dt20                 dt20_bytes  dt27                         dt27_bytes
2015-09-11 11:26:00  4          2015-09-11 11:25:42.417  8         2015-09-11 11:25:42  6           2015-09-11 11:25:42.4170000  8

그래서 정보를 두 번째로 저장하려고한다면 - 밀리 세컨드가 아닌 - datetime 또는 datetime2 (7) 대신 datetime2 (0)를 사용하면 각각 2 바이트를 절약 할 수 있습니다.




날짜 문자열을 datetimedatetime2 로 해석하는 것은 미국 이외의 DATEFORMAT 설정을 사용할 때도 다를 수 있습니다. 예 :

set dateformat dmy
declare @d datetime, @d2 datetime2
select @d = '2013-06-05', @d2 = '2013-06-05'
select @d, @d2

그러면 datetime 에 대해 2013-05-06 (즉 5 월 6 일)이 반환되고 6 월 5 일에 2013-06-05 가 반환됩니다. 그러나 dateformatmdy 설정하면 @d@d2 모두 2013-06-05 반환합니다.

datetime 동작은 SET DATEFORMATMSDN 설명서불일치합니다 . ISO 8601과 같은 일부 문자열 형식은 DATEFORMAT 설정과 별도로 해석 됩니다. 분명히 사실이 아닙니다!

내가 이것에 물릴 때까지는 언어 / 로케일 설정에 관계없이 yyyy-mm-dd 날짜가 올바르게 처리 될 것이라고 항상 생각했습니다.




이 기사 에 따르면 DateTime2를 사용하여 DateTime과 동일한 정밀도를 사용하려면 DateTime2 (3)를 사용해야합니다. 이것은 동일한 정밀도를 제공하고, 더 적은 바이트를 사용하며, 확장 된 범위를 제공해야합니다.




이전 질문 ...하지만 여기에 다른 사람이 이미 언급하지 않은 것을 추가하고 싶습니다 ... (참고 : 이것은 내 자신의 관찰이므로 참조를 요구하지 마십시오)

Datetime2는 필터 조건에서 사용될 때 더 빠릅니다.

TLDR :

SQL 2016에서는 정확한 시간을 초까지 저장해야했기 때문에 십만 행의 테이블과 날짜 시간 열 ENTRY_TIME이있었습니다. 많은 조인과 하위 쿼리를 사용하여 복잡한 쿼리를 실행하는 동안 where 절을 다음과 같이 사용했습니다.

WHERE ENTRY_TIME >= '2017-01-01 00:00:00' AND ENTRY_TIME < '2018-01-01 00:00:00'

쿼리는 처음에는 수백 개의 행이있을 때 좋았지 만 행 수가 증가하면 쿼리에서이 오류가 발생하기 시작했습니다.

Execution Timeout Expired. The timeout period elapsed prior
to completion of the operation or the server is not responding.

where 절을 제거했는데 예기치 않게 모든 날짜의 모든 행을 가져 왔지만 1 초 안에 쿼리가 실행되었습니다. where 절로 내부 쿼리를 실행하면 85 초가 걸리고 where 절을 사용하지 않으면 0.01 초가 걸립니다.

datetime 필터링 성능 으로이 문제에 대한 많은 스레드가 여기에 왔습니다.

최적화 된 쿼리. 하지만 실제 속도는 datetime 열을 datetime2로 변경하는 것입니다.

이제 이전에 시간 초과 된 동일한 쿼리가 1 초도 채 걸리지 않습니다.

건배




Select ValidUntil + 1
from Documents

위의 SQL은 DateTime2 필드에서 작동하지 않습니다. 그것은 반환하고 오류 "피연산자 유형 충돌 : datetime2는 int와 호환되지 않습니다"

다음 날을 얻기 위해 1을 더하는 것은 개발자들이 수년간 날짜를 가지고 수행해온 것입니다. 이제 Microsoft는이 간단한 기능을 처리 할 수없는 새로운 datetime2 필드를 사용합니다.

"이전 유형보다 더 나쁜 새로운 유형을 사용합시다."라고 나는 생각하지 않는다!






Related