Spaltengröße mit Datentyp dezimal

7

Laut BOL für SQL Server 2008 R2 erfordert der Datentyp Dezimal die folgenden Speicherbytes:

Precision  Storage bytes

1 - 9      =>   5

10-19      => 9

20-28      => 13

29-38      => 17

Wenn ich jedoch eine Datenlänge () für eine Spalte mache, die dezimal (19,5) formatiert ist und den Wert 10999.99999 hat, erhalte ich 5 Bytes zurück? Das ist nach meinem Verständnis eine Genauigkeit von 10 und nicht von 9 und sollte zu 9 Bytes führen.

Dies führt zu zwei Fragen:

  1. Hängt die Größe der Tabelle mit dieser Spalte nicht von der Spaltendefinition ab, sondern definieren die wahren Werte innerhalb der Spalte die Tabellengröße?

  2. Warum stimmen die Informationen in BOL nicht mit den Daten überein, die () zurückgibt?

nojetlag
quelle
Zeigen Sie uns bitte genaues SQL
gbn
Der Grenzwert für die DATALENGTHMeldung von 5 oder 9 Bytes in diesem Fall scheint 42949.67295(gespeichert als 01 FF FF FF FF 00 00 00 00) und 42949.67296(gespeichert als 01 00 00 00 00 01 00 00 00) zu sein. Ich bin mir nicht sicher, wie nützlich dieses Verhalten genau ist!
Martin Smith
CREATE TABLE [Test195]( [Date] [date] NULL, [Time] [time](3) NULL, [CCYPairID] [tinyint] NULL, [Price] [decimal](19, 5) NULL, [Amount] [bigint] NULL, ) SELECT [Date] ,[Time] ,[CCYPairID] ,DATALENGTH([CCYPairID]) as CByte ,[Price] ,DATALENGTH([Price]) as PByte ,[Amount] ,DATALENGTH([Amount]) as AByte FROM [Test195]
Nojetlag

Antworten:

6

Mischen Sie nicht Speicher (5 oder 9 Bytes) und was Sie zurückbekommen

In einer Dezimalspalte (19,5) sind es immer 9 Bytes auf der Festplatte. Null benötigt also neun Bytes.

Sie 10999.99999sind lediglich eine Darstellung dieser gespeicherten Nummer, die dann von DATALENGTH als 10999.99999 analysiert wird

Bearbeiten:

DATALENGTH gibt die Anzahl der Bytes zurück, die zum Speichern des angegebenen Ausdrucks erforderlich sind. Der Datentyp wird meistens ignoriert . Wird 10999.99999also als Dezimalzahl (10,5) behandelt , die in 5 Bytes und nicht in 9 Bytes gespeichert werden kann , wie Martin in einem Kommentar hervorhob.

Eine Dezimalspalte (19,5) besteht also immer aus 9 Bytes. DATALENGTH ist das egal. Es betrachtet den Ausdruck 10999.99999und entscheidet, dass er in 5 Bytes gespeichert werden kann. Aber natürlich kann es nicht

Persönlich habe ich DATALENGTH nie verwendet, außer um Leerzeichen oder ähnliches zu finden.

Verwenden Sie DATALENGTH grundsätzlich nicht für Datentypen ohne Zeichenfolge.

Gibt die Anzahl der Bytes zurück, die zur Darstellung eines Ausdrucks verwendet werden.

DATALENGTH ist besonders nützlich bei Datentypen varchar, varbinary, text, image, nvarchar und ntext, da diese Datentypen Daten variabler Länge speichern können.

Hinweis: LEN gibt an, wie lang die Zeichenfolgendarstellung ist

DECLARE @i decimal(19,5)
SET @i ='10999.99999'
SELECT @i,LEN(@i),DATALENGTH(@i)
SET @i ='-90999.99999'
SELECT @i,LEN(@i),DATALENGTH(@i)
gbn
quelle
Sie sagen also, dass datalength () mir nur die Bytes gibt, die zum Anzeigen der angegebenen Spalte benötigt werden, aber die tatsächliche Größe auf der Festplatte variiert? Ich habe einige Tests mit tinyint und money durchgeführt und dort stimmte die Anzahl der Bytes mit der überein, die ich laut Dokumentation erwartet hätte. Ich stelle diese Fragen, weil ich ungefähr 13 Milliarden Zeilen in einer Tabelle habe und den Durchsatz selbst im schlimmsten Fall eines vollständigen Tabellenscans optimieren möchte. Wäre in diesem Fall die Bytegröße aus dem Speicher oder die Bytegröße für die Anzeige von Bedeutung? (Im Moment brauche ich ca. 15 Minuten für einen vollständigen Tabellenscan)
Nojetlag
Es gibt keine Optimierung für einen vollständigen Tabellenscan. Konzentrieren Sie sich nicht auf das, was Ihnen eine unangemessene Funktion bietet: Denken Sie an die Indizierung oder Partitionierung oder Archivierung
gbn