datetime2 (0) vs datetime2 (2)

15

Gemäß der Dokumentation datetime2 (Transact-SQL) :

Speichergröße
6 Bytes für Präzisionen kleiner als 3.
7 Bytes für Präzisionen 3 und 4.
Alle anderen Präzisionen erfordern 8 Bytes.

Die Größe datetime2(0), datetime2(1), datetime2(2)verwenden die gleiche Menge an Speicher (6 Bytes).

Würde ich zu Recht sagen, dass ich genauso gut datetime2(2)die Präzision nutzen könnte, ohne zusätzliche Kosten für die Größe zu verursachen?

Bitte beachten Sie:

  • Diese Spalte wird mit der PK indiziert, um einen zusammengesetzten Clustered-Index zu bilden (der für die Tabellenpartitionierung verwendet wird).
  • Millisekunden interessieren mich nicht

Wäre datetime2(0)die CPU-Effizienz höher, wenn sie in einer where-Klausel oder beim Durchsuchen eines Index verwendet würde?

Dies ist eine massive Tabelle, daher wird die kleinste Optimierung einen großen Unterschied machen.

Zapnologica
quelle

Antworten:

26

Die Größe von dateTime2 (0), dateTime2 (1), dateTime2 (2), dateTime2 (3) beansprucht den gleichen Speicherplatz. (6 Bytes)

Wäre es richtig zu sagen, dass ich genauso gut mit dateTime2 (3) arbeiten und die Präzision ohne zusätzliche Größenkosten nutzen könnte.

Nein, Sie haben die Dokumentation falsch interpretiert. Beachten Sie, dass das Dokument eine Speichergröße von 6 Byte für Präzisionen von weniger als 3 angibt (Hervorhebung meiner). Eine Genauigkeit von 3 erfordert also 7 Bytes.

Wenn Sie sich nicht für Millisekunden interessieren, ist datetime2(0)dies der richtige Datentyp und die richtige Genauigkeit. Die beste Vorgehensweise besteht darin, den richtigen Datentyp und die richtige Genauigkeit basierend auf den gespeicherten Daten anzugeben, da dies von Natur aus eine optimale Speicherung und Effizienz bietet. Abgesehen davon würde ich keine signifikanten Leistungseinbußen aufgrund der angegebenen Genauigkeit von datetime2 erwarten, solange die Speichergröße dieselbe ist, aber ich habe das selbst nicht speziell getestet.

Die Anwendungsanforderungen bestimmen, was in der Datenbank gespeichert werden muss, wenn in der Quelle eine höhere Genauigkeit verfügbar ist. Beispielsweise SYSDATETIME()möchten Benutzer für eine Auftragserfassungszeit von möglicherweise keine 100-Nanosekunden-Genauigkeit. Wählen Sie erneut den Datentyp und die Genauigkeit für die Neuentwicklung entsprechend den Anforderungen, und Sie erhalten im Allgemeinen eine optimale Leistung, ohne zusätzliche Überlegungen anzustellen:

  • Datum - Sie brauchen keine Zeit
  • smalldatetime - Sie brauchen keine Sekunden
  • datetime2 (0) - Sie benötigen keine Sekundenbruchteile
  • datetime2 (1-7) - Sie benötigen Sekundenbruchteile mit der angegebenen Genauigkeit
  • datetimeoffset (0-7) - Sie benötigen Datum und Uhrzeit mit Zeitzonenerkennung
  • Zeit (0-7) - Sie benötigen nur Zeit (kein Datum) mit Sekundenbruchteilen der angegebenen Genauigkeit

Obwohl datetime2 für die oben aufgeführte Neuentwicklung am besten geeignet ist, muss möglicherweise stattdessen datetime (feste Genauigkeit 3 ​​mit einer Genauigkeit von 1/300 Sekundenbruchteilen) verwendet werden, um die Kompatibilität mit älteren datetime-Anwendungen zu gewährleisten. Auf diese Weise werden implizite Konvertierungen und unerwartetes Vergleichsverhalten vermieden der Aufwand für Sekundenbruchteilgenauigkeit und erhöhte Speicherkapazität.

Bedenken Sie, dass das Speichern einer größeren Präzision als erforderlich auch Entwicklungskosten verursachen kann. Wenn eine Zeitkomponente mit Sekundenbruchteilen gespeichert wird und nur eine Genauigkeit von einer Sekunde erforderlich ist, müssen Abfragen die Sekundenbruchteile berücksichtigen, um die korrekten Ergebnisse zu erhalten. Beispielsweise müsste bei einer App, bei der der Benutzer einen Zeitbereich über eine Benutzeroberfläche auswählt, der nur ganze Sekunden zulässt, der App-Code die Sekundenbruchteile im Wert des Endzeitbereichs berücksichtigen und den vom Benutzer angegebenen Wert entsprechend anpassen (z. B. WHERE OrderEntryTime BETWEEN '2017-01-11T08:00:00.00.00' AND '2017-01-11T08:59:59.99'oder WHERE OrderEntryTime >= '2017-01-11T08:00:00.00' AND OrderEntryTime < '2017-01-11T09:00:00.00'). Dies erhöht die Codekomplexität.

Dan Guzman
quelle
Tut mir leid, dass ich diesen alten Thread nur für diese winzige Notiz anstoßen muss, aber smalldatetime hat ganze Sekunden (dh hh: mm: ss).
pgfiore
@pgfiore Bist du dir da sicher?
Peter Vandivier
@pgweiterhin wird in der smalldatetimeDokumentation die Genauigkeit von einer Minute angegeben, und Sie werden feststellen, dass sie korrekt ist SELECT CAST(GETDATE() AS smalldatetime);.
Dan Guzman