DateTime2 so với DateTime trong SQL Server


762

Cái nào:

những cách đề nghị cho đến nay cửa hàng và thời gian trong SQL Server 2008+?

Tôi nhận thấy sự khác biệt về độ chính xác (và có thể là không gian lưu trữ), nhưng bỏ qua những điều đó cho đến bây giờ, có tài liệu thực hành tốt nhất về thời điểm sử dụng cái gì, hoặc có lẽ chúng ta chỉ nên sử dụng datetime2?

Câu trả lời:


641

Tài liệu MSDN cho datetime khuyến nghị sử dụng datetime2 . Đây là khuyến nghị của họ:

Sử dụng time, date, datetime2datetimeoffsetcác kiểu dữ liệu cho công việc mới. Các loại này phù hợp với Tiêu chuẩn SQL. Chúng di động hơn. time, datetime2datetimeoffset cung cấp thêm giây chính xác. datetimeoffsetcung cấp hỗ trợ múi giờ cho các ứng dụng được triển khai trên toàn cầu.

datetime2 có phạm vi ngày lớn hơn, độ chính xác phân đoạn mặc định lớn hơn và độ chính xác do người dùng chỉ định tùy chọn. Cũng tùy thuộc vào độ chính xác do người dùng chỉ định, nó có thể sử dụng ít bộ nhớ hơn.


46
trong khi có độ chính xác tăng với datetime2, một số khách hàng không hỗ trợ ngày, giờ hoặc datetime2 và buộc bạn phải chuyển đổi thành một chuỗi bằng chữ. Nếu bạn quan tâm nhiều hơn đến khả năng tương thích hơn độ chính xác, hãy sử dụng datetime
FistOfFury

4
Một tùy chọn khác là sử dụng chế độ xem được lập chỉ mục với cột được chuyển đổi dưới dạng datetime để tương thích. Tuy nhiên, bạn sẽ cần có thể trỏ ứng dụng vào chế độ xem.
TamusJRoyce

9
Hỗ trợ múi giờ với DATETIMEOFFSET là một cách viết sai. Nó chỉ lưu trữ một bù UTC trong một thời gian cụ thể, không phải là múi giờ.
Suncat2000

6
@Porad: Chính xác thì lợi ích gì trong thực tế là "" dễ mang theo hơn "do là" Tiêu chuẩn SQL "? Đó là ngoài việc bạn viết nhiều mã hơn đáng kể có thể đọc / duy trì đáng kể cho một" cổng "sang RDBMS khác mà có thể sẽ không bao giờ xảy ra trong vòng đời của mã đó. Khác với các công cụ và Trình điều khiển SQL Server do Microsoft cung cấp (thậm chí), có bất kỳ ứng dụng nào thực sự dựa vào các biểu diễn cấp Bit cụ thể của DateTime2Loại (hoặc bất kỳ Máy chủ SQL nào khác không Gõ cho vấn đề đó)? Xem Nhược điểm trong 7/10/17 của tôi Trả lời bên dưới để biết lý do tôi hỏi
Tom

2
@Adam Porad: Ngoài ra, tất cả những lợi ích đó có thể không cần thiết (bên ngoài các ứng dụng khoa học hoặc khoa học) và do đó không đáng để mất lợi ích nhiều, rất có thể cần thiết: khả năng dễ dàng hơn (thậm chí xem xét cách giải quyết) để chuyển đổi hoàn toàn / rõ ràng một số có dấu phẩy động (số ngày bao gồm nếu appl., ngày phân số kể từ thời gian ngày tối thiểu) cho các phép cộng, phép trừ, mức tối thiểu, mức tối đa và mức trung bình. Xem Nhược điểm trong câu trả lời 7/10/17 của tôi dưới đây để biết chi tiết.
Tom

493

DATETIME2có phạm vi ngày từ "0001/01/01" đến " DATETIME9999/12/31 " trong khi loại chỉ hỗ trợ năm 1753-9999.

Ngoài ra, nếu bạn cần, DATETIME2có thể chính xác hơn về mặt thời gian; DATETIME được giới hạn trong 3 1/3 mili giây, trong khi DATETIME2có thể chính xác xuống tới 100ns.

Cả hai loại ánh xạ tới System.DateTime.NET - không có sự khác biệt ở đó.

Nếu bạn có sự lựa chọn, tôi sẽ khuyên bạn nên sử dụng DATETIME2bất cứ khi nào có thể. Tôi không thấy bất kỳ lợi ích nào khi sử dụng DATETIME(ngoại trừ khả năng tương thích ngược) - bạn sẽ ít gặp rắc rối hơn (với ngày nằm ngoài phạm vi và rắc rối như thế).

Ngoài ra, nếu bạn chỉ cần ngày (không có phần thời gian), hãy sử dụng NGÀY - nó cũng tốt như vậy DATETIME2và cũng giúp bạn tiết kiệm không gian! :-) Tương tự chỉ dành cho thời gian - sử dụng TIME. Đó là những gì các loại đang có!


158
Hãy cẩn thận khi thêm giá trị .NET DateTime làm tham số cho SqlCommand, vì nó thích giả sử đó là loại thời gian cũ và bạn sẽ gặp lỗi nếu bạn cố gắng viết giá trị DateTime nằm ngoài phạm vi 1753-9999 năm đó trừ khi bạn chỉ định rõ ràng loại là System.Data.SqlDbType.DateTime2 cho SqlParameter. Dù sao, datetime2 là tuyệt vời, bởi vì nó có thể lưu trữ bất kỳ giá trị nào có thể được lưu trữ trong loại .NET DateTime.
Triynko

10
@marc_s - Không phải đó là null để làm gì sao?
JohnFx

8
@JohnFX - hơi muộn ở đây - nhưng bạn sẽ không đặt datetime thành null. bạn sẽ sử dụng Nullable <datetime> hay datetime? xử lý null tốt - và trong ánh xạ tới một Proc chỉ đơn giản là làm param.value = someDateTime ?? DBValue.Null Thật không may, chúng tôi bị mắc kẹt với một kiểu dữ liệu với một số sau nó - dường như rất 'chung chung' :)
Adam Tuliper - MSFT

69
Lol, tôi chỉ cố gắng nâng cao nhận xét của riêng tôi (ở trên), trước khi tôi nhận ra đó là nhận xét của riêng tôi (được thực hiện hơn một năm trước). Tôi vẫn đang xử lý quyết định thiết kế ngu ngốc của .NET framework để TRUNCATE tất cả các giá trị DateTime theo mặc định khi được chuyển dưới dạng SqlParameter trừ khi bạn đặt nó thành SqlDbType.DateTime2 chính xác hơn. Quá nhiều cho việc tự động suy ra đúng loại. Thực sự, họ nên thực hiện thay đổi một cách minh bạch, thay thế việc triển khai phạm vi giới hạn, kém hiệu quả, kém chính xác hơn và giữ nguyên tên loại "datetime" ban đầu. Xem thêm stackoverflow.com/q/8421332/88409
Triynko

5
@marc_s Đó không phải Nullable<DateTime>là để làm gì?
ChrisW

207

datetime2 chiến thắng ở hầu hết các khía cạnh ngoại trừ (ứng dụng cũ Khả năng tương thích)

  1. phạm vi giá trị lớn hơn
  2. độ chính xác tốt hơn
  3. không gian lưu trữ nhỏ hơn (nếu độ chính xác do người dùng chỉ định được chỉ định)

Các kiểu dữ liệu ngày và giờ của SQL so sánh - datetime, datetime2, date, TIME

xin lưu ý những điểm sau

  • Cú pháp
    • datetime2 [(độ chính xác giây phân đoạn => Xem bên dưới Kích thước lưu trữ)]
  • Chính xác, quy mô
    • 0 đến 7 chữ số, với độ chính xác 100ns.
    • Độ chính xác mặc định là 7 chữ số.
  • Kích thước lưu trữ
    • 6 byte cho độ chính xác nhỏ hơn 3;
    • 7 byte cho độ chính xác 3 và 4.
    • Tất cả độ chính xác khác yêu cầu 8 byte .
  • DateTime2 (3) có cùng số chữ số với DateTime nhưng sử dụng 7 byte lưu trữ thay vì 8 byte ( SQLHINTS- DateTime Vs DateTime2 )
  • Tìm hiểu thêm về datetime2 (bài viết MSDN của Transact-SQL)

nguồn hình ảnh: Bộ công cụ đào tạo tự nhịp độ MCTS (Bài kiểm tra 70-432): Microsoft® SQL Server® 2008 - Triển khai và bảo trì Chương 3: Bảng -> Bài 1: Tạo bảng -> trang 66


7
Cảm ơn vì đã hiển thị số liệu thống kê +1 cho nó, datetime2thật tuyệt vời (Người chiến thắng)
Pankaj Parkar

2
@Iman Abidi: Theo nhận xét của Oskar Berggren ngày 10 tháng 9 năm 2014 lúc 3:51 chiều trên bài viết "SQLHINTS- DateTime Vs DateTime2" mà bạn đã tham chiếu: "datetime2 (3) KHÔNG giống như datetime. Họ sẽ có cùng số. bằng chữ số, nhưng độ chính xác của datetime là 3,33ms, trong khi độ chính xác của datetime2 (3) là 1ms. "
Tom

1
@PankajParkar: Woah, không quá nhanh. Bạn có thể muốn xem phần Nhược điểm trong Câu trả lời của tôi ngày 7/10/17 dưới đây.
Tom

Làm thế nào để datetime2sử dụng ít không gian lưu trữ hơn datetimevà cung cấp một phạm vi lớn hơn và độ chính xác cao hơn?
Đại

107

Tôi đồng tình với @marc_s và @Adam_Poward - DateTime2 là phương pháp ưa thích để tiến lên. Nó có phạm vi ngày rộng hơn, độ chính xác cao hơn và sử dụng dung lượng lưu trữ bằng hoặc ít hơn (tùy thuộc vào độ chính xác).

Một điều mà cuộc thảo luận đã bỏ lỡ, tuy nhiên ...
@Marc_s tuyên bố : Both types map to System.DateTime in .NET - no difference there. Điều này là chính xác, tuy nhiên, điều ngược lại là không đúng ... và nó quan trọng khi thực hiện tìm kiếm trong phạm vi ngày (ví dụ: "tìm cho tôi tất cả các bản ghi được sửa đổi vào ngày 5/5/2010").

Phiên bản .NET Datetimecó phạm vi và độ chính xác tương tự DateTime2. Khi ánh xạ một .net Datetimexuống SQL cũ DateTimemột tròn tiềm ẩn xảy ra . SQL cũ DateTimechính xác đến 3 mili giây. Điều này có nghĩa 11:59:59.997là gần đến mức bạn có thể đến cuối ngày. Bất cứ điều gì cao hơn được làm tròn lên đến ngày hôm sau.

Thử cái này :

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'

Tránh làm tròn ẩn này là một lý do quan trọng để chuyển sang DateTime2. Làm tròn số ngày rõ ràng gây nhầm lẫn:


14
Bạn cũng có thể tránh làm tròn số này bằng cách không cố gắng tìm "kết thúc" của một ngày nào. > = 5 tháng 5 VÀ <6 tháng 5 an toàn hơn nhiều và sẽ hoạt động trên bất kỳ loại ngày / giờ nào (ngoại trừ TIME tất nhiên). Cũng đề nghị tránh các định dạng khu vực, mơ hồ như m / d / yyyy.
Aaron Bertrand

2
@AaronBertrand - hoàn toàn đồng ý, nhưng nhìn vào số lượng câu hỏi chúng tôi có vấn đề có vẻ đáng để mô tả.
EBarr

1
Tại sao bạn chuyển từ 20100505tới 5/5/2010? Định dạng cũ sẽ hoạt động với bất kỳ khu vực nào trong SQL Server. Cái sau sẽ vỡ: SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')oops:2015-07-01 00:00:00.000
ErikE

1
@EBarr: Re. "DateTime2 là phương pháp ưa thích di chuyển về phía trước. Nó có phạm vi ngày rộng hơn, độ chính xác cao hơn và sử dụng dung lượng bằng hoặc ít hơn (tùy thuộc vào độ chính xác": Tôi hoàn toàn không đồng ý. Xem phần Nhược điểm trong Câu trả lời của tôi ngày 7/10/17 dưới đây Nói tóm lại, những lợi ích đó có thể không cần thiết (bên ngoài các ứng dụng khoa học / khoa học) và do đó không đáng để mất các lợi ích RẤT NHIỀU cần thiết hơn, khả năng dễ dàng hơn (thậm chí xem xét cách giải quyết) để chuyển đổi hoàn toàn / rõ ràng thành một số dấu phẩy động ( # của ngày bao gồm nếu appl., phân số kể từ giá trị thời gian tối thiểu) cho +, - và avg.
Tom

20

Hầu như tất cả các Câu trả lời và Nhận xét đều nặng về Ưu điểm và nhẹ về Nhược điểm. Đây là bản tóm tắt của tất cả Ưu và Nhược điểm cho đến nay cộng với một số Nhược điểm quan trọng (ở mục số 2 bên dưới) Tôi chỉ thấy được đề cập một lần hoặc không.

  1. PROS:

1.1. Tuân thủ ISO nhiều hơn (ISO 8601) (mặc dù tôi không biết làm thế nào điều này đi vào thực tế).

1.2. Nhiều phạm vi hơn (1/1/0001 đến 12/12/9999 so với 1/1 / 1753-12 / 31/9999) (mặc dù phạm vi bổ sung, tất cả trước năm 1753, có thể sẽ không được sử dụng ngoại trừ, ví dụ: trong các ứng dụng lịch sử, thiên văn, địa chất, vv).

1.3. Chính xác phù hợp với phạm vi phạm vi DateTimeLoại của .NET (mặc dù cả hai chuyển đổi qua lại không có mã hóa đặc biệt nếu các giá trị nằm trong phạm vi và độ chính xác của loại mục tiêu ngoại trừ Con # 2.1 bên dưới sẽ xảy ra lỗi / làm tròn số khác).

1.4. Độ chính xác cao hơn (100 nano giây hay 0,000,000,1 giây so với 3,33 mili giây hay 0,003,33 giây) (mặc dù độ chính xác bổ sung có thể sẽ không được sử dụng trừ ví dụ, trong các ứng dụng kỹ thuật / khoa học).

1.5. Khi được cấu hình cho tương tự (như trong 1 millisec không "giống nhau" (như trong 3,33 millisec) như Iman Abidi đã tuyên bố) chính xác nhưDateTime , sử dụng ít không gian hơn (7 so với 8 byte), nhưng dĩ nhiên, bạn sẽ mất lợi ích chính xác có khả năng là một trong hai (phạm vi khác) được chào mời nhiều nhất mặc dù có thể là lợi ích không cần thiết).

  1. Nhược điểm:

2.1. Khi truyền tham số cho .NET SqlCommand, bạn phải chỉ định System.Data.SqlDbType.DateTime2nếu bạn có thể truyền giá trị bên ngoài SQL ServerDateTime phạm vi và / hoặc độ chính xác hay không, bởi vì nó mặc định là System.Data.SqlDbType.DateTime.

2.2. Không thể được chuyển đổi ngầm định / dễ dàng thành giá trị số dấu phẩy động (# ngày kể từ ngày tối thiểu) để thực hiện các thao tác sau với / trong nó trong các biểu thức SQL Server bằng cách sử dụng các giá trị số và toán tử:

2.2.1. cộng hoặc trừ # ngày hoặc một phần ngày. Lưu ý: Sử dụngDateAdd Hàm như một cách giải quyết không phải là chuyện nhỏ khi bạn cần xem xét nhiều nếu không phải là tất cả các phần của thời gian.

2.2.2. lấy sự khác biệt giữa hai lần tính thời gian cho các mục đích tính toán của tuổi age. Lưu ý: DateDiffThay vào đó, bạn không thể đơn giản sử dụng Chức năng của SQL Server , vì nó không tính toán agenhư hầu hết mọi người mong đợi ở chỗ nếu hai thời gian ngày xảy ra vượt qua ranh giới thời gian theo lịch / đồng hồ của các đơn vị được chỉ định ngay cả đối với một phần rất nhỏ của đơn vị đó, nó sẽ trả phần chênh lệch như 1 trong tổng số đơn vị so với 0. Ví dụ, DateDifftrong Daylà hai ngày-thời gian chỉ 1 mili giây ngoài sẽ trở lại 1 vs 0 (ngày) nếu những ngày-thời gian được tính vào các ngày theo lịch khác nhau (ví dụ: 1999 1999-31 23: 59: 59.9999999, và 2000-01-01 00: 00: 00.0000000,). Thời gian chênh lệch 1 mili giây giống nhau nếu được di chuyển để chúng không vượt qua một ngày theo lịch, sẽ trả về một Ngày DateDiff Cá trong Day0 (ngày).

2.2.3. lấy Avgthời gian ngày tháng (trong Truy vấn tổng hợp) bằng cách chuyển đổi sang kiểu Float Float trước rồi sau đó quay lại DateTime.

LƯU Ý: Để chuyển đổi DateTime2thành số, bạn phải thực hiện một số công thức như công thức sau mà vẫn giả sử giá trị của bạn không thấp hơn năm 1970 (có nghĩa là bạn sẽ mất tất cả phạm vi bổ sung cộng thêm 217 năm nữa. không thể đơn giản điều chỉnh công thức để cho phép phạm vi bổ sung vì bạn có thể gặp phải các sự cố tràn số.

25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0- Nguồn: “ https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html

Tất nhiên, bạn cũng có thể Castđến DateTimeđầu tiên (và nếu cần thiết trở lại một lần nữa để DateTime2), nhưng bạn sẽ mất sự chính xác và phạm vi (tất cả trước năm 1753) lợi ích của DateTime2vs DateTimeđó là prolly 2 lớn nhất và cũng đồng thời prolly 2 khả năng cần thiết ít nhất đặt ra câu hỏi tại sao lại sử dụng nó khi bạn mất các chuyển đổi ngầm định / dễ dàng thành số dấu phẩy động (# ngày) cho phép cộng / trừ / "tuổi" (so với DateDiff) /Avg calcs lợi ích lớn theo kinh nghiệm của tôi.

Btw, Avgthời gian ngày là (hoặc ít nhất nên là) một trường hợp sử dụng quan trọng. a) Bên cạnh việc sử dụng trong việc lấy thời lượng trung bình khi thời gian ngày (kể từ thời gian ngày cơ sở chung) được sử dụng để biểu thị thời lượng (thông lệ chung), b) cũng rất hữu ích để có được thống kê loại bảng điều khiển về ngày trung bình- thời gian nằm trong cột thời gian của một phạm vi / nhóm Hàng. c) Truy vấn đặc biệt (hoặc ít nhất phải là tiêu chuẩn) để theo dõi / khắc phục các giá trị trong Cột có thể không còn hiệu lực bao giờ / lâu hơn nữa và / hoặc có thể cần được phản đối là liệt kê cho mỗi giá trị số lần xuất hiện và (nếu có) Min, AvgMaxtem thời gian được liên kết với giá trị đó.


1
Giống như quan điểm trái ngược - nó chỉ ra phía c # của phương trình. Kết hợp với tất cả các "ưu điểm" khác, nó sẽ cho phép mọi người đưa ra lựa chọn tốt dựa trên nơi họ muốn chịu nỗi đau.
EBarr

1
@EBarr: Chỉ phần Nhược điểm số 1 trong "view quan điểm trái ngược" của tôi chỉ ra phía c # của phương trình ". Phần còn lại (Nhược điểm 2.2.1 - 2.2.3), như tôi đã nói là những lợi ích rất cần thiết (của DateTime), đều liên quan đến các hiệu ứng trên các câu hỏi và câu lệnh của SQL Server.
Tom

Re 2.2.1 - nó được coi là một thực hành không an toàn để thực hiện số học vào các ngày và cách ưa thích là luôn sử dụng DateAdd và các hàm liên quan. Đây là thực hành tốt nhất. Có trách nhiệm nghiêm trọng để thực hiện số học ngày, không phải là ít nhất trong số đó là nó không hoạt động đối với hầu hết các loại ngày. Một vài bài viết: sqlservercentral.com/bloss/ cấp sqlblog.org/2011/09/20/iêu
RBerman

@RBerman: Re. "Không an toàn": Nó chỉ không an toàn với một số loại ngày nhất định (như DateTime2tôi đã đề cập (do khả năng tràn cao)). Re. "không hoạt động đối với hầu hết các loại ngày": Bạn chỉ cần nó hoạt động với một loại và hầu hết các ngày trong hầu hết các ứng dụng có thể sẽ không bao giờ cần phải chuyển đổi sang loại ngày khác trong toàn bộ thời gian sống của chúng (ngoại trừ, như tôi cũng đã đề cập , DateTime2để DateTime(ví dụ: thực hiện "số học vào ngày"; P). Do đó, không có giá trị mã hóa bổ sung trong các truy vấn nghiên cứu không chỉ được lập trình mà còn sử dụng loại ngày thân thiện với số học.
Tom

15

DateTime2 sẽ tàn phá nếu bạn là nhà phát triển Access đang cố gắng viết Now () vào trường được đề cập. Vừa thực hiện một lần di chuyển Access -> SQL 2008 R2 và nó đặt tất cả các trường datetime dưới dạng DateTime2. Nối một bản ghi với Now () khi giá trị bị đánh bom. Không sao vào 1/1/2012 2:53:04 PM, nhưng không phải vào 1/10/2012 2:53:04 PM.

Một khi nhân vật đã tạo ra sự khác biệt. Hy vọng nó sẽ giúp được ai đó.


15

Dưới đây là một ví dụ sẽ cho bạn thấy sự khác biệt về kích thước lưu trữ (byte) và độ chính xác giữa smalldatetime, datetime, datetime2 (0) và 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

trả về

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

Vì vậy, nếu tôi muốn lưu trữ thông tin xuống giây - nhưng không phải đến mili giây - tôi có thể lưu 2 byte mỗi lần nếu tôi sử dụng datetime2 (0) thay vì datetime hoặc datetime2 (7).


10

trong khi có độ chính xác tăng với datetime2 , một số khách hàng không hỗ trợ ngày , giờ hoặc datetime2 và buộc bạn phải chuyển đổi thành một chuỗi bằng chữ. Cụ thể, Microsoft đề cập đến các vấn đề ODBC, OLE DB, JDBC và SqlClient "xuống cấp" với các loại dữ liệu này và có một biểu đồ cho thấy mỗi loại có thể ánh xạ loại.

Nếu giá trị tương thích trên độ chính xác, sử dụng datetime


10

Câu hỏi cũ ... Nhưng tôi muốn thêm một cái gì đó chưa được ai nêu ở đây ... (Lưu ý: Đây là quan sát của riêng tôi, vì vậy đừng hỏi bất kỳ tài liệu tham khảo nào)

Datetime2 nhanh hơn khi được sử dụng trong tiêu chí lọc.

TLDR:

Trong SQL 2016 tôi đã có một bảng có hàng trăm nghìn hàng và cột datetime ENTRY_TIME vì nó được yêu cầu lưu trữ thời gian chính xác lên đến giây. Trong khi thực hiện một truy vấn phức tạp có nhiều phép nối và truy vấn phụ, khi tôi sử dụng mệnh đề where là:

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

Truy vấn ban đầu khá ổn khi có hàng trăm hàng, nhưng khi số lượng hàng tăng lên, truy vấn bắt đầu đưa ra lỗi này:

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

Tôi đã xóa mệnh đề where và không ngờ, truy vấn đã được chạy trong 1 giây, mặc dù bây giờ TẤT CẢ các hàng cho tất cả các ngày đã được tìm nạp. Tôi chạy truy vấn bên trong với mệnh đề where và mất 85 giây và không có mệnh đề where thì mất 0,01 giây.

Tôi đã gặp nhiều chủ đề ở đây cho vấn đề này như hiệu suất lọc datetime

Tôi tối ưu hóa truy vấn một chút. Nhưng tốc độ thực sự tôi có được là bằng cách thay đổi cột datetime thành datetime2.

Bây giờ cùng một truy vấn đã hết thời gian trước đó mất ít hơn một giây.

chúc mừng


9

Giải thích các chuỗi ngày vào datetimedatetime2cũng có thể khác nhau, khi sử dụng các DATEFORMATcài đặt không phải của Hoa Kỳ . Ví dụ

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

Điều này trả về 2013-05-06(tức là ngày 6 tháng 5) cho datetime2013-06-05(tức là ngày 5 tháng 6) cho datetime2. Tuy nhiên, với dateformatthiết lập mdy, cả @d@d2trả về 2013-06-05.

Các datetimehành vi có vẻ mâu thuẫn với tài liệu MSDN của SET DATEFORMATđó nêu rõ: Một số định dạng chuỗi ký tự, ví dụ như ISO 8601, được giải thích một cách độc lập của các thiết lập DateFormat . Rõ ràng là không đúng!

Cho đến khi tôi bị cắn bởi điều này, tôi luôn nghĩ rằng yyyy-mm-ddngày sẽ được xử lý đúng, bất kể cài đặt ngôn ngữ / ngôn ngữ.


2
Không. Đối với ISO 8601 tôi nghĩ bạn có nghĩa là YYYYMMDD (không có dấu gạch ngang).SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;Hãy thử lại với dấu gạch ngang.
Aaron Bertrand

1
Tiêu chuẩn cho phép cả hai định dạng YYYY-MM-DD và YYYYMMDD cho các biểu diễn ngày theo lịch. Tôi nghĩ MSDN nên cụ thể hơn về tập hợp con nào của đặc tả ISO 8601 được diễn giải độc lập!
Richard Fawcett

1
Tôi biết điều đó nhưng trong SQL Server chỉ có cú pháp không dấu gạch ngang là an toàn.
Aaron Bertrand

6

Theo bài viết này , nếu bạn muốn có cùng độ chính xác của DateTime bằng DateTime2, bạn chỉ cần sử dụng DateTime2 (3). Điều này sẽ cung cấp cho bạn độ chính xác tương tự, chiếm ít hơn một byte và cung cấp phạm vi mở rộng.


Để rõ ràng, nó có độ chính xác tương tự như datetime SQL, không phải là .NET DateTime.
Sam Ruither

Đó là chính xác, tôi giả sử mọi người sẽ hiểu bối cảnh nhưng giá trị của nó cụ thể.
jKlaus

4

Tôi chỉ tình cờ tìm thấy một lợi thế nữa DATETIME2: nó tránh được một lỗi trong adodbapimô-đun Python , nó sẽ nổ tung nếu một datetimegiá trị thư viện tiêu chuẩn được truyền qua có một micro giây không cho một DATETIMEcột nhưng hoạt động tốt nếu cột được định nghĩa là DATETIME2.


0
Select ValidUntil + 1
from Documents

SQL ở trên sẽ không hoạt động với trường DateTime2. Nó trả về và lỗi "Kiểu toán tử clash: datetime2 không tương thích với int"

Thêm 1 để có được ngày hôm sau là điều mà các nhà phát triển đã làm với ngày trong nhiều năm. Bây giờ Microsoft có một trường datetime2 siêu mới không thể xử lý chức năng đơn giản này.

"Hãy sử dụng loại mới này tệ hơn loại cũ", tôi không nghĩ vậy!


2
Vì vậy, chúng tôi rõ ràng ở đây datetimedatetime2các loại dữ liệu đều được giới thiệu trong SQL Server 2008. Bạn cũng nhận được Operand type clash: date is incompatible with inttừ dateloại đã xuất hiện kể từ ngày chấm. Tất cả ba loại dữ liệu chỉ hoạt động tốt với dateadd(dd, 1, ...)mặc dù.
Luôn luôn học

2
Điều này không rõ ràng. Tôi có cơ sở dữ liệu SQLServer 2005 với trường datetime trong đó.
Paul McCarthy

0

Tôi nghĩ DATETIME2là cách tốt hơn để lưu trữ date, bởi vì nó có hiệu quả hơn DATETIME. Trong SQL Server 2008bạn có thể sử dụng DATETIME2, nó lưu trữ ngày và giờ, mất 6-8 bytesđể lưu trữ và có độ chính xác 100 nanoseconds. Vì vậy, bất cứ ai cần thời gian chính xác hơn sẽ muốn DATETIME2.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.