Saya telah membuat tabel dengan 650 Numeric (19,4) kolom. Ketika saya mengaktifkan Page Compression, dengan menjalankan
ALTER TABLE fct.MyTable REBUILD WITH (DATA_COMPRESSION = PAGE);
saya mendapat
Msg 1975, Level 16, State 1
Indeks 'PK_Mytable' panjang baris melebihi panjang maksimum yang diijinkan dari '8060' byte.
tetapi 650 kali 9 byte hanya 5850 byte, yang cukup jauh dari batas yang dinyatakan 8060 byte.
Server menjalankan Windows 2012 r2 dengan SQL Server 2016 SP1 CU2
Berapakah biaya baris saat menggunakan Kompresi Halaman?
Berikut ini beberapa kode untuk menunjukkan apa yang saya maksud:
/* 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
Kompresi baris juga gagal, tetapi pada jumlah baris yang berbeda.
sql-server-2016
compression
data-pages
Henrik Staun Poulsen
sumber
sumber
Jawaban:
Jika Anda mencoba membuat tabel Anda tanpa Kendala PK berkerumun, dan Anda akan mendapatkan kesalahan yang sedikit berbeda:
Dalam pesan kesalahan ini, Anda dapat melihat bahwa ada 1530 byte overhead internal untuk kompresi halaman.
Sekarang, Anda dapat melakukan perhitungan:
bigint
MyTableIDint
Kolom Terakhirnumeric(19,4)
kolom (total 5337 byte)Jadi, 8 + 4 + (593 * 9) + 1530 = 6879. Tunggu sebentar .... Itu masih di bawah 8060. Ada apa dengan itu ?!
Algoritma Kompresi Halaman sebenarnya menumpuk beberapa algoritma kompresi bersama. Langkah pertama adalah menerapkan kompresi ROW. Overhead kompresi baris tidak termasuk dalam 1530 byte overhead yang tercantum dalam pesan kesalahan itu.
Anda dapat membaca lebih lanjut tentang cara kompresi baris bekerja di sini di blog saya dan di sini di BOL . Anda akan mencatat di artikel BOL yang menggambarkan
numeric
penyimpanan sebagai "Penyimpanan ini persis sama dengan format penyimpanan vardecimal," tetapi tidak menjelaskanvardecimal
. Posting ini mencakupvardecimal
sedikit lebih banyak - pada dasarnya, ia menambahkan 2 byte overhead per kolom untuk menyimpan panjang sebenarnya (mirip dengan apa yangvarchar
dilakukan).Kompresi baris akan membutuhkan tambahan 2 byte untuk masing-masing dari 593
numeric
kolom, ditambahbigint
danint
akan membutuhkan 1 byte masing-masing overhead.The baris-dikompresi persyaratan penyimpanan akan menjadi:
bigint
MyTableIDint
LastColumnnumeric(19,4)
kolom8 + 4 + (593 * 9) = 5349 byte data
1 + 1 + (593 * 2) = 1188 byte kompresi baris atas
Total 6537 byte untuk skema kompresi baris
Sekarang kita memiliki ukuran baris untuk skema terkompresi baris, kita dapat meninjau kembali matematika kita. Ukuran baris yang dikompresi halaman akan menjadi ukuran data + overhead kompresi baris + overhead kompresi halaman:
bigint
MyTableIDint
Kolom Terakhirnumeric(19,4)
kolomTotal 8067 byte
sumber