DateTime2 vs DateTime in SQL Server

762

Welcher:

ist die empfohlene Methode zum Speichern von Datum und Uhrzeit in SQL Server 2008+?

Ich bin mir der Unterschiede in der Präzision (und wahrscheinlich im Speicherplatz) bewusst, aber wenn ich diese vorerst ignoriere, gibt es ein Best-Practice-Dokument darüber, wann was zu verwenden ist, oder sollten wir vielleicht nur verwenden datetime2?

Mikeon
quelle

Antworten:

641

In der MSDN-Dokumentation für datetime wird die Verwendung von datetime2 empfohlen . Hier ist ihre Empfehlung:

Verwenden Sie die time, date, datetime2und datetimeoffsetDatentypen für neue Arbeit. Diese Typen stimmen mit dem SQL-Standard überein. Sie sind tragbarer. time, datetime2Und datetimeoffset mehr Sekunden Präzision. datetimeoffsetBietet Zeitzonenunterstützung für global bereitgestellte Anwendungen.

datetime2 hat einen größeren Datumsbereich, eine größere Standard-Bruchgenauigkeit und eine optionale benutzerdefinierte Genauigkeit. Abhängig von der benutzerdefinierten Genauigkeit wird möglicherweise weniger Speicherplatz benötigt.

Adam Porad
quelle
46
Während datetime2 eine höhere Genauigkeit aufweist, unterstützen einige Clients Datum, Uhrzeit oder datetime2 nicht und zwingen Sie zur Konvertierung in ein Zeichenfolgenliteral. Wenn Sie mehr über Kompatibilität als über Präzision besorgt sind, verwenden Sie datetime
FistOfFury
4
Eine andere Option ist die Verwendung einer indizierten Ansicht, wobei die Spalte aus Kompatibilitätsgründen als Datum / Uhrzeit konvertiert wird. Sie müssen jedoch in der Lage sein, die App auf die Ansicht zu verweisen.
TamusJRoyce
9
Die Unterstützung von Zeitzonen mit DATETIMEOFFSET ist eine Fehlbezeichnung. Es wird nur ein UTC-Offset für einen bestimmten Zeitpunkt gespeichert, nicht für eine Zeitzone.
Suncat2000
6
@Porad: Was genau ist der Vorteil in der Praxis, "" portabler "zu sein, weil es" SQL Standard "ist? Außerdem schreiben Sie deutlich mehr Code, der für einen" Port "wesentlich weniger lesbar / wartbar ist, als ein anderer wird wahrscheinlich nie für die Lebensdauer dieses Codes auftreten. Abgesehen von möglicherweise von Microsoft bereitgestellten SQL Server-Tools und -Treibern (falls überhaupt) gibt es Apps, die tatsächlich auf den spezifischen Darstellungen auf DateTime2Bitebene des Typs (oder einem anderen SQL Server ) basieren Typ für diese Angelegenheit)? Siehe die Nachteile in meiner 7/10/17 Antwort unten, warum ich frage.
Tom
2
@Adam Porad: Außerdem sind all diese Vorteile wahrscheinlich nicht erforderlich (außerhalb von technischen oder wissenschaftlichen Apps) und daher den Verlust von Vorteilen nicht viel wert, VIEL wahrscheinlicher: die viel einfachere (selbst unter Berücksichtigung von Problemumgehungen) Fähigkeit, implizit / explizit zu konvertieren ein numerischer Gleitkommawert (Anzahl der Tage inkl., falls zutreffend, gebrochene Tage seit dem Mindestdatum) für Additionen, Subtraktionen, Minima, Maxima und Mittelwerte. Siehe die Nachteile in meiner Antwort vom 10.07.17 unten für Details.
Tom
493

DATETIME2hat einen Datumsbereich von "0001/01/01" bis " DATETIME9999/12/31 ", während der Typ nur das Jahr 1753-9999 unterstützt.

Wenn nötig, DATETIME2kann dies auch zeitlich genauer sein. DATETIME ist auf 3 1/3 Millisekunden begrenzt und DATETIME2kann auf 100 ns genau sein.

Beide Typen sind System.DateTimein .NET zugeordnet - da gibt es keinen Unterschied.

Wenn Sie die Wahl haben, würde ich empfehlen, DATETIME2wann immer möglich zu verwenden. Ich sehe keine Vorteile bei der Verwendung DATETIME(außer bei der Abwärtskompatibilität) - Sie werden weniger Probleme haben (mit Daten, die außerhalb des Bereichs liegen und solche Probleme verursachen).

Plus: Wenn Sie nur das Datum (ohne Zeitangabe) benötigen, verwenden Sie DATE - es ist genauso gut wie DATETIME2und spart Ihnen auch Platz! :-) Gleiches gilt nur für die Zeit - verwenden TIME. Dafür sind diese Typen da!

marc_s
quelle
158
Seien Sie vorsichtig, wenn Sie einem SqlCommand einen .NET DateTime-Wert als Parameter hinzufügen, da davon ausgegangen wird, dass es sich um den alten Datetime-Typ handelt. Wenn Sie versuchen, einen DateTime-Wert zu schreiben, der außerhalb des Bereichs von 1753 bis 9999 Jahren liegt, wird eine Fehlermeldung angezeigt es sei denn, Sie geben den Typ explizit als System.Data.SqlDbType.DateTime2 für den SqlParameter an. Auf jeden Fall ist datetime2 großartig, da es jeden Wert speichern kann, der im .NET DateTime-Typ gespeichert werden kann.
Triynko
10
@marc_s - Ist das nicht was für null ist?
JohnFx
8
@ JohnFX - etwas spät hier - aber Sie würden keine Datums- / Uhrzeitzeit auf null setzen. Sie würden Nullable <Datetime> oder Datetime verwenden? was null gut behandelt - und bei der Zuordnung zu einem Prozess würde einfach param.value = someDateTime ?? DBValue.Null Sein unglückliches sind wir mit einem Datentyp mit einer Reihe stecken , nachdem es - gerade so ‚generischen‘ scheint:)
Adam Tuliper - MSFT
69
Lol, ich habe gerade versucht, meinen eigenen Kommentar (oben) zu verbessern, bevor mir klar wurde, dass es mein eigener Kommentar war (vor über einem Jahr). Ich beschäftige mich immer noch mit der dummen Entwurfsentscheidung des .NET Frameworks, standardmäßig alle DateTime-Werte zu TRUNCIEREN, wenn sie als SqlParameters übergeben werden, es sei denn, Sie setzen sie explizit auf den genaueren SqlDbType.DateTime2. Soviel zum automatischen Ableiten des richtigen Typs. Eigentlich hätten sie die Änderung transparent machen und die weniger präzise, ​​weniger effiziente Implementierung mit begrenztem Bereich ersetzen und den ursprünglichen Typnamen "datetime" beibehalten sollen. Siehe auch stackoverflow.com/q/8421332/88409
Triynko
5
@marc_s Ist das nicht was Nullable<DateTime>?
ChrisW
207

datetime2 gewinnt in den meisten Aspekten außer (Kompatibilität mit alten Apps)

  1. größerer Wertebereich
  2. bessere Genauigkeit
  3. kleinerer Speicherplatz (wenn optionale benutzerdefinierte Genauigkeit angegeben ist)

SQL Datums- und Zeitdatentypen vergleichen - Datum / Uhrzeit, Datum / Uhrzeit2, Datum, ZEIT

Bitte beachten Sie die folgenden Punkte

  • Syntax
    • datetime2 [(Sekundenbruchteilgenauigkeit => Unter Speichergröße suchen)]
  • Präzisionswaage
    • 0 bis 7 Stellen mit einer Genauigkeit von 100 ns.
    • Die Standardgenauigkeit beträgt 7 Stellen.
  • Speichergröße
    • 6 Bytes für eine Genauigkeit von weniger als 3;
    • 7 Bytes für Genauigkeit 3 ​​und 4.
    • Alle anderen Genauigkeiten erfordern 8 Bytes .
  • DateTime2 (3) hat die gleiche Anzahl von Ziffern wie DateTime, verwendet jedoch 7 Byte Speicher anstelle von 8 Byte ( SQLHINTS-DateTime Vs DateTime2 ).
  • Weitere Informationen finden Sie unter datetime2 (Transact-SQL MSDN-Artikel)

Bildquelle: MCTS Self-Paced Training Kit (Prüfung 70-432): Microsoft® SQL Server® 2008 - Implementierung und Wartung Kapitel 3: Tabellen -> Lektion 1: Erstellen von Tabellen -> Seite 66

Iman
quelle
7
Vielen Dank für die datetime2
Anzeige
2
@Iman Abidi: Laut Oskar Berggrens Kommentar vom 10. September 2014 um 15:51 Uhr zu dem Artikel "SQLHINTS-DateTime Vs DateTime2", auf den Sie verwiesen haben: "datetime2 (3) ist NICHT identisch mit datetime. Sie haben dieselbe Nummer von Ziffern, aber die Genauigkeit von datetime beträgt 3,33 ms, während die Genauigkeit von datetime2 (3) 1 ms beträgt. "
Tom
1
@PankajParkar: Woah, nicht so schnell. Vielleicht möchten Sie den Abschnitt Nachteile meiner Antwort vom 10.07.17 unten lesen.
Tom
Wie verbraucht datetime2man weniger Speicherplatz als datetimeund bietet dennoch eine größere Reichweite und höhere Präzision?
Dai
107

Ich stimme @marc_s und @Adam_Poward zu - DateTime2 ist die bevorzugte Methode für die Zukunft. Es verfügt über einen größeren Datumsbereich, eine höhere Genauigkeit und verwendet (je nach Genauigkeit) den gleichen oder einen geringeren Speicherplatz.

Eines hat die Diskussion jedoch verpasst ...
@Marc_s besagt : Both types map to System.DateTime in .NET - no difference there. Dies ist richtig, aber die Umkehrung ist nicht wahr ... und es ist wichtig, wenn Datumsbereichssuchen durchgeführt werden (z. B. "Finde alle Datensätze, die am 05.05.2010 geändert wurden").

Die .NET-Version von Datetimehat eine ähnliche Reichweite und Präzision wie DateTime2. Wenn ein .net Datetimedem alten SQL zugeordnet wird, erfolgt DateTimeeine implizite Rundung . Das alte SQL DateTimeist auf 3 Millisekunden genau. Dies bedeutet, dass Sie 11:59:59.997so nah wie möglich am Ende des Tages sind. Alles, was höher ist, wird auf den nächsten Tag aufgerundet.

Versuche dies :

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'

Das Vermeiden dieser impliziten Rundung ist ein wichtiger Grund, auf DateTime2 umzusteigen. Die implizite Rundung von Daten führt eindeutig zu Verwirrung:

EBarr
quelle
14
Sie können diese Rundung auch vermeiden, indem Sie ohnehin nicht versuchen, das "Ende" eines Tages zu finden. > = 5. Mai UND <6. Mai ist viel sicherer und funktioniert für jeden Datums- / Zeittyp (außer natürlich ZEIT). Vermeiden Sie auch regionale, mehrdeutige Formate wie m / t / jjjj.
Aaron Bertrand
2
@ AaronBertrand - stimme vollkommen zu, aber angesichts der Anzahl der Fragen, die wir haben, schien es sich zu lohnen, sie zu beschreiben.
EBarr
1
Warum bist du von 20100505zu 5/5/2010gewechselt? Das erstere Format funktioniert mit jeder Region in SQL Server. Letzteres wird brechen: SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')oops:2015-07-01 00:00:00.000
ErikE
1
@ Ebarr: Re. "DateTime2 ist die bevorzugte Methode für die Zukunft. Es hat einen größeren Datumsbereich, eine höhere Genauigkeit und verwendet gleichen oder weniger Speicher (abhängig von der Genauigkeit": Ich bin absolut anderer Meinung. Siehe den Abschnitt "Nachteile" meiner Antwort vom 10.07.17 unten Kurz gesagt, diese Vorteile sind wahrscheinlich nicht erforderlich (außerhalb von technischen / wissenschaftlichen Apps) und daher den Verlust von Vorteilen, die VIEL wahrscheinlicher benötigt werden, nicht wert. Die einfachere (selbst unter Berücksichtigung von Problemumgehungen) Möglichkeit, implizit / explizit in eine Gleitkommazahl zu konvertieren ( Anzahl der Tage inkl. falls zutreffend, Brüche seit min Datum-Uhrzeit) Wert für +, - und Durchschnitt
Tom
20

Fast alle Antworten und Kommentare waren schwer für die Vor- und Nachteile. Hier ist eine Zusammenfassung aller Vor- und Nachteile sowie einige wichtige Nachteile (in Nr. 2 unten), die ich nur einmal oder gar nicht erwähnt habe.

  1. PROS:

1.1. ISO-konformer (ISO 8601) (obwohl ich nicht weiß, wie dies in der Praxis zum Tragen kommt).

1.2. Mehr Reichweite (1/1/0001 bis 12/31/9999 vs. 1/1 / 1753-12 / 31/9999) (obwohl die zusätzliche Reichweite, alle vor dem Jahr 1753, wahrscheinlich nicht verwendet wird, außer z. in historischen, astronomischen, geologischen usw. Apps).

1.3. Stimmt genau mit dem Bereich des .NET- DateTimeTyps überein (obwohl beide ohne spezielle Codierung vor und zurück konvertieren, wenn die Werte innerhalb des Bereichs und der Genauigkeit des Zieltyps liegen, mit Ausnahme von Con # 2.1 unten, da sonst Fehler / Rundungen auftreten).

1.4. Mehr Präzision (100 Nanosekunden alias 0,000,000,1 Sek. Gegenüber 3,33 Millisekunden alias 0,003,33 Sek.) (Obwohl die zusätzliche Präzision wahrscheinlich nicht verwendet wird, außer zum Beispiel in technischen / wissenschaftlichen Apps).

1.5. Bei einer Konfiguration für ähnliche (wie in 1 Millisekunde nicht "gleich" (wie in 3,33 Millisekunden), wie Iman Abidi behauptet hat) Präzision wie DateTimewird weniger Speicherplatz benötigt (7 gegenüber 8 Bytes), aber dann würden Sie natürlich die verlieren Präzisionsvorteil, der wahrscheinlich einer der beiden am meisten angepriesenen Vorteile ist (der andere ist der Bereich), wenn auch wahrscheinlich nicht benötigte Vorteile).

  1. Nachteile:

2.1. Wenn Sie einen Parameter an ein .NET übergeben SqlCommand, müssen Sie angeben, System.Data.SqlDbType.DateTime2ob Sie möglicherweise einen Wert außerhalb des DateTimeBereichs und / oder der Genauigkeit von SQL Server übergeben , da dieser standardmäßig verwendet wird System.Data.SqlDbType.DateTime.

2.2. Kann nicht implizit / einfach in einen numerischen Gleitkommawert (Anzahl der Tage seit dem Mindestdatum / der Mindestzeit) konvertiert werden, um in SQL Server-Ausdrücken mit numerischen Werten und Operatoren Folgendes zu tun:

2.2.1. Addiere oder subtrahiere Anzahl von Tagen oder Teiltagen. Hinweis: Die Verwendung der DateAddFunktion als Problemumgehung ist nicht trivial, wenn Sie mehrere, wenn nicht alle Teile der Datums- und Uhrzeitangabe berücksichtigen müssen.

2.2.2. Nehmen Sie die Differenz zwischen zwei Datums- und Uhrzeitangaben für die Berechnung des Alters. Hinweis: Sie können DateDiffstattdessen nicht einfach die SQL Server- Funktion verwenden, da sie nicht so berechnet wird, agewie es die meisten Benutzer erwarten würden, wenn die beiden Datums- und Uhrzeitangaben eine Kalender- / Uhrzeit-Datums- / Uhrzeitgrenze der angegebenen Einheiten überschreiten, wenn auch nur für einen winzigen Bruchteil diese Einheit, wird es gibt die Differenz als 1 diese Einheit gegen 0. Zum Beispiel kann die DateDiffin Day‚s von zwei Daten mal nur 1 Millisekunde auseinander 1 vs. 0 (Tage) zurück , wenn diese Datum-Zeiten sind an verschiedenen Kalendertagen (dh "1999-12-31 23: 59: 59.9999999" und "2000-01-01 00: 00: 00.0000000"). Die gleichen Datums- und Uhrzeitunterschiede von 1 Millisekunde, wenn sie verschoben werden, damit sie keinen Kalendertag überschreiten, geben ein "DateDiff" in Day0 (Tagen) zurück.

2.2.3. Nehmen Sie die AvgDatums- und Uhrzeitangaben (in einer aggregierten Abfrage), indem Sie einfach zuerst in "Float" und dann wieder zurück in "Float" konvertieren DateTime.

HINWEIS: Um DateTime2in eine Zahl umzuwandeln , müssen Sie etwa die folgende Formel ausführen, bei der immer noch davon ausgegangen wird, dass Ihre Werte nicht unter dem Jahr 1970 liegen (was bedeutet, dass Sie den gesamten zusätzlichen Bereich plus weitere 217 Jahre verlieren. Hinweis: Möglicherweise Sie können die Formel nicht einfach anpassen, um einen zusätzlichen Bereich zu ermöglichen, da möglicherweise Probleme mit dem numerischen Überlauf auftreten.

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

Natürlich könnte man auch Castzu DateTimeersten (und ggf. wieder zu DateTime2), aber Sie würden die Genauigkeit und Reichweite (alle vor dem Jahr 1753) Vorteile verlieren DateTime2gegen DateTimedie prolly zugleich die 2 größten und auch prolly sind Die 2 am wenigsten benötigten, die die Frage aufwirft, warum sie verwendet werden, wenn Sie die impliziten / einfachen Konvertierungen in Gleitkommazahlen ( Anzahl der Tage) für Addition / Subtraktion / "Alter" (vs. DateDiff) / AvgBerechnungsvorteil verlieren, was ein großer Vorteil ist durch meine Erfahrung.

Übrigens ist das AvgDatum und die Uhrzeit ein wichtiger Anwendungsfall (oder sollte es zumindest sein). a) Neben der Verwendung zum Ermitteln der durchschnittlichen Dauer, wenn Datums- und Uhrzeitangaben (da eine gemeinsame Basisdatum-Uhrzeit) zur Darstellung der Dauer verwendet wird (eine gängige Praxis), ist es b) auch nützlich, eine Dashboard-Statistik über das durchschnittliche Datum zu erhalten. Die Uhrzeit befindet sich in der Datums- / Uhrzeitspalte eines Bereichs / einer Gruppe von Zeilen. c) Eine Standard- Ad-hoc-Abfrage (oder sollte zumindest Standard sein) zur Überwachung / Fehlerbehebung von Werten in einer Spalte, die möglicherweise nie / nicht mehr gültig ist und / oder möglicherweise veraltet sein muss, besteht darin, für jeden Wert die Anzahl der Vorkommen aufzulisten und (falls vorhanden) die Min, Avgund MaxDatum-Zeitstempel mit dem Wert zugeordnet.

Tom
quelle
1
Wie die konträre Sichtweise zeigt sie die c # -Seite der Gleichung auf. In Kombination mit all den anderen "Profis" können Menschen eine gute Wahl treffen, je nachdem, wo sie ihre Schmerzen lindern möchten.
EBarr
1
@EBarr: Nur der Cons # 1-Teil meiner "'Contrarian View'" "weist auf die c # -Seite der Gleichung hin". Der Rest (Cons # 2.2.1 - 2.2.3), die, wie gesagt, die weitaus wahrscheinlicher benötigten Vorteile DateTimesind, beziehen sich alle auf Auswirkungen auf SQL Server-Abfragen und -Anweisungen.
Tom
Zu 2.2.1 - Es wird als unsichere Praxis angesehen, an Daten zu rechnen, und die bevorzugte Methode ist immer die Verwendung von DateAdd und verwandten Funktionen. Dies ist eine bewährte Methode. Es gibt ernsthafte Verpflichtungen bei der Datumsarithmetik, nicht zuletzt, dass dies für die meisten Datumstypen nicht funktioniert. Einige Artikel: sqlservercentral.com/blogs/… sqlblog.org/2011/09/20/…
RBerman
@RBerman: Re. "unsicher": Es ist nur bei bestimmten Datumstypen unsicher (wie die DateTime2bereits erwähnten (aufgrund der hohen Wahrscheinlichkeit eines Überlaufs)). Re. "funktioniert nicht für die meisten Datumstypen": Sie benötigen es nur, um mit einem zu arbeiten, und die meisten Daten in den meisten Apps müssen wahrscheinlich nie für ihre gesamte Lebensdauer in einen anderen Datumstyp konvertiert werden (außer vielleicht, wie ich auch erwähnt habe) , DateTime2um DateTime(z. B. "Arithmetik an Datumsangaben" durchzuführen; P). Angesichts dessen ist es nicht die gesamte zusätzliche Codierung in nicht nur programmierten, sondern auch Ad-hoc-Forschungsabfragen wert, einen nicht arithmetikfreundlichen Datumstyp zu verwenden.
Tom
15

DateTime2 verursacht Chaos, wenn Sie als Access-Entwickler versuchen, Now () in das betreffende Feld zu schreiben. Habe gerade eine Access -> SQL 2008 R2-Migration durchgeführt und alle datetime-Felder als DateTime2 eingefügt. Anhängen eines Datensatzes mit Now () als bombardiertem Wert. Es war okay am 01.01.2012 14:53:04 Uhr, aber nicht am 10.01.2012 14:53:04 Uhr.

Einmal machte der Charakter den Unterschied. Hoffe es hilft jemandem.

Rhett A Brown
quelle
15

Hier ist ein Beispiel, das Ihnen die Unterschiede in der Speichergröße (Bytes) und der Genauigkeit zwischen smalldatetime, datetime, datetime2 (0) und datetime2 (7) zeigt:

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

was zurückkehrt

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

Wenn ich also Informationen auf die Sekunde - aber nicht auf die Millisekunde - speichern möchte, kann ich jeweils 2 Bytes speichern, wenn ich datetime2 (0) anstelle von datetime oder datetime2 (7) verwende.

Baodad
quelle
10

während mit datetime2 die Genauigkeit erhöht wird , hat einige Kunden nicht unterstützen Datum , Zeit oder datetime2 und zwingen Sie zu einem Stringliteral zu konvertieren. Insbesondere erwähnt Microsoft ODBC-, OLE DB-, JDBC- und SqlClient-Probleme auf "niedriger Ebene" mit diesen Datentypen und verfügt über ein Diagramm, das zeigt, wie jeder den Typ zuordnen kann.

Wenn Wert Kompatibilität über Präzision, Gebrauch Datetime

Faust der Wut
quelle
10

Alte Frage ... Aber ich möchte hier etwas hinzufügen, das noch niemand gesagt hat ... (Hinweis: Dies ist meine eigene Beobachtung, fragen Sie also nicht nach einer Referenz.)

Datetime2 ist schneller, wenn es in Filterkriterien verwendet wird.

TLDR:

In SQL 2016 hatte ich eine Tabelle mit hunderttausend Zeilen und einer Datetime-Spalte ENTRY_TIME, da die genaue Zeit bis zu Sekunden gespeichert werden musste. Während ich eine komplexe Abfrage mit vielen Verknüpfungen und einer Unterabfrage ausführte, verwendete ich die where-Klausel als:

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

Die Abfrage war anfangs in Ordnung, wenn Hunderte von Zeilen vorhanden waren. Als jedoch die Anzahl der Zeilen zunahm, gab die Abfrage den folgenden Fehler aus:

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

Ich habe die where-Klausel entfernt und unerwartet wurde die Abfrage in 1 Sekunde ausgeführt, obwohl jetzt ALLE Zeilen für alle Daten abgerufen wurden. Ich führe die innere Abfrage mit der where-Klausel aus, und es dauerte 85 Sekunden, und ohne der where-Klausel dauerte es 0,01 Sekunden.

Ich bin hier auf viele Threads für dieses Problem als Datetime-Filterleistung gestoßen

Ich habe die Abfrage etwas optimiert. Aber die wirkliche Geschwindigkeit, die ich bekam, war das Ändern der datetime-Spalte in datetime2.

Jetzt dauert dieselbe Abfrage, für die zuvor eine Zeitüberschreitung aufgetreten ist, weniger als eine Sekunde.

Prost

MJ Khan
quelle
9

Die Interpretation von Datumszeichenfolgen in datetimeund datetime2kann auch unterschiedlich sein, wenn DATEFORMATEinstellungen außerhalb der USA verwendet werden. Z.B

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

Dies gibt 2013-05-06(dh den 6. Mai) für datetimeund 2013-06-05(dh den 5. Juni) für zurück datetime2. Mit dateformatset to mdy, both @dund @d2return 2013-06-05.

Das datetimeVerhalten scheint im Widerspruch zu der MSDN-Dokumentation zu stehen, in SET DATEFORMATder es heißt: Einige Zeichenfolgenformate, z. B. ISO 8601, werden unabhängig von der Einstellung DATEFORMAT interpretiert . Offensichtlich nicht wahr!

Bis ich davon gebissen wurde, hatte ich immer gedacht, dass yyyy-mm-ddDaten unabhängig von den Sprach- / Gebietsschemaeinstellungen richtig gehandhabt werden.

Richard Fawcett
quelle
2
Nee. Für ISO 8601 meinten Sie JJJJMMTT (keine Bindestriche). SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;Versuchen Sie es erneut mit den Strichen.
Aaron Bertrand
1
Der Standard erlaubt die Formate JJJJ-MM-TT und JJJJMMTT für die Darstellung von Kalenderdaten. Ich denke, MSDN sollte genauer angeben, welche Teilmenge der ISO 8601-Spezifikation unabhängig interpretiert wird!
Richard Fawcett
1
Ich weiß, dass aber in SQL Server nur die No-Dash-Syntax sicher ist.
Aaron Bertrand
6

Laut diesem Artikel müssen Sie einfach DateTime2 (3) verwenden, wenn Sie mit DateTime2 die gleiche Genauigkeit von DateTime erzielen möchten. Dies sollte Ihnen die gleiche Genauigkeit bieten, ein Byte weniger beanspruchen und einen erweiterten Bereich bieten.

jKlaus
quelle
Um es klar auszudrücken, ist es die gleiche Genauigkeit wie SQL datetime, keine .NET DateTime.
Sam Rueby
Das ist richtig, ich ging davon aus, dass jeder den Kontext verstehen würde, aber es lohnt sich, dies ausdrücklich zu erwähnen.
jKlaus
4

Ich bin gerade auf einen weiteren Vorteil gestoßen DATETIME2: Es vermeidet einen Fehler im Python- adodbapiModul, der explodiert, wenn ein Standardbibliothekswert übergeben datetimewird, der Mikrosekunden ungleich Null für eine DATETIMESpalte hat, aber gut funktioniert, wenn die Spalte als definiert ist DATETIME2.

Bob Kline
quelle
0
Select ValidUntil + 1
from Documents

Das obige SQL funktioniert nicht mit einem DateTime2-Feld. Es wird zurückgegeben und der Fehler "Operandentyp clash: datetime2 ist nicht kompatibel mit int"

Das Hinzufügen von 1 für den nächsten Tag ist etwas, was Entwickler seit Jahren mit Daten tun. Jetzt hat Microsoft ein super neues datetime2-Feld, das diese einfache Funktionalität nicht verarbeiten kann.

"Verwenden wir diesen neuen Typ, der schlechter ist als der alte", glaube ich nicht!

Paul McCarthy
quelle
2
Nur so sind wir hier klar die datetimeund datetime2Datentypen wurden in SQL Server eingeführt beide 2008. Sie erhalten auch Operand type clash: date is incompatible with intvon der dateArt , die seit dem ersten Tag dot schon hat. Alle drei Datentypen funktionieren jedoch dateadd(dd, 1, ...)einwandfrei.
AlwaysLearning
2
Das ist nicht klar. Ich habe eine SQLServer 2005-Datenbank mit einem Datum / Uhrzeit-Feld.
Paul McCarthy
0

Ich denke, es DATETIME2ist der bessere Weg, das zu speichern date, weil es effizienter ist als das DATETIME. In können SQL Server 2008Sie verwenden DATETIME2, es speichert ein Datum und eine Uhrzeit, dauert 6-8 byteszum Speichern und hat eine Genauigkeit von 100 nanoseconds. Wer also mehr Zeitpräzision braucht, wird es wollen DATETIME2.

James
quelle