Ich habe eine Tabelle mit 650 numerischen (19,4) Spalten erstellt. Wenn ich die Seitenkomprimierung einschalte, indem ich laufe
ALTER TABLE fct.MyTable REBUILD WITH (DATA_COMPRESSION = PAGE);
Ich bekomme
Meldung 1975, Ebene 16,
Status 1 Index 'PK_Mytable' Zeilenlänge überschreitet die maximal zulässige Länge von '8060' Bytes.
650 mal 9 Bytes sind jedoch nur 5850 Bytes, was ziemlich weit von der angegebenen Grenze von 8060 Bytes entfernt ist.
Auf dem Server wird Windows 2012 r2 mit SQL Server 2016 SP1 CU2 ausgeführt
Wie hoch ist der Zeilenaufwand bei Verwendung der Seitenkomprimierung?
Hier ist ein Code, der zeigt, was ich meine:
/* test script to demo MSG 1975 */
DECLARE @sql NVARCHAR(max)='', @i INT =0
drop table if exists dbo.mytable;
SET @sql = 'Create table dbo.Mytable (MyTableID bigint not null
identity(1,1) primary key clustered, '
WHILE @i < 593 BEGIN
SET @sql += ' Column' + LTRIM(@i) + ' numeric(19,4) null, '
SET @i +=1
END
SET @sql += ' LastColumn int) '
--SET @sql += ' with (DATA_COMPRESSION = ROW) '
SET @sql += ' with (DATA_COMPRESSION = PAGE) '
SELECT @sql
EXEC sys.sp_executesql @sql
SELECT top 10000 * FROM dbo.MyTable MT
Die Zeilenkomprimierung schlägt ebenfalls fehl, jedoch mit einer anderen Zeilenanzahl.
sql-server-2016
compression
data-pages
Henrik Staun Poulsen
quelle
quelle
Antworten:
Wenn Sie versuchen, Ihre Tabelle ohne die gruppierte PK-Einschränkung zu erstellen, wird ein etwas anderer Fehler angezeigt:
In dieser Fehlermeldung sehen Sie, dass 1530 Byte interner Overhead für die Seitenkomprimierung vorhanden sind.
Jetzt können Sie rechnen:
bigint
MyTableIDint
LastColumnnumeric(19,4)
Spalten (insgesamt 5337 Bytes)Also, 8 + 4 + (593 * 9) + 1530 = 6879. Moment mal ... Das ist immer noch unter 8060. Was ist damit los?!
Der Seitenkomprimierungsalgorithmus stapelt tatsächlich mehrere Komprimierungsalgorithmen zusammen. Der erste Schritt besteht darin, die ROW-Komprimierung anzuwenden. Der Overhead der Zeilenkomprimierung ist nicht in den in dieser Fehlermeldung aufgeführten 1530 Bytes Overhead enthalten.
Weitere Informationen zur Funktionsweise der Zeilenkomprimierung finden Sie hier in meinem Blog und hier in BOL . Sie werden im BOL-Artikel feststellen, dass der
numeric
Speicher als "Dieser Speicher entspricht genau dem vardezimalen Speicherformat" beschrieben wird, dies wird jedoch nicht erläutertvardecimal
. Dieser Beitrag behandeltvardecimal
etwas mehr - im Wesentlichen werden 2 Byte Overhead pro Spalte hinzugefügt, um die tatsächliche Länge zu speichern (ähnlich wie bei dervarchar
Ausführung).Die Zeilenkomprimierung erfordert zusätzliche 2 Bytes für jede der 593
numeric
Spalten sowie diebigint
undint
erfordert jeweils 1 Byte Overhead.Die zeilenkomprimierten Speicheranforderungen wären:
bigint
MyTableIDint
LastColumnnumeric(19,4)
Spalten8 + 4 + (593 * 9) = 5349 Byte Daten
1 + 1 + (593 * 2) = 1188 Byte Zeilenkomprimierungsaufwand
Insgesamt 6537 Byte für zeilenkomprimiertes Schema
Nachdem wir die Zeilengröße für das zeilenkomprimierte Schema haben, können wir unsere Mathematik erneut überprüfen. Die seitenkomprimierte Zeilengröße entspricht der Datengröße + dem Zeilenkomprimierungsaufwand + dem Seitenkomprimierungsaufwand:
bigint
MyTableIDint
LastColumnnumeric(19,4)
Spalten8067 Bytes insgesamt
quelle