Implementazione della compressione di riga

Si applica a:SQL ServerDatabase SQL di AzureIstanza gestita di SQL di Azure

In questo articolo vengono riepilogate le modalità di implementazione della compressione di riga nel motore di database. Tale riepilogo fornisce informazioni di base che consentono di pianificare lo spazio di archiviazione necessario per i dati.

L'abilitazione della compressione modifica solo il formato di archiviazione fisica dei dati associato a un tipo di dati, ma non la relativa sintassi o semantica. Le modifiche alle applicazioni non sono obbligatorie quando una o più tabelle sono abilitate per la compressione. Al nuovo formato di archiviazione del record sono associate le seguenti modifiche principali:

  • Riduzione dell'overhead di metadati associati al record. Tali metadati rappresentano informazioni su colonne e sui relativi offset e lunghezze. In alcuni casi, l'overhead di metadati potrebbe essere maggiore del formato di archiviazione obsoleto.

  • Uso del formato di archiviazione a lunghezza variabile per i tipi numerici (come integer, decimale float) e i tipi basati su quello numerico (come datetime e money).

  • Archiviazione di stringhe di caratteri a lunghezza fissa utilizzando un formato a lunghezza variabile senza archiviare i caratteri vuoti.

Nota

Ottimizzazione dei valori NULL e 0 per tutti i tipi di dati in modo che non occupino alcun byte.

Influenza della compressione di riga sull'archiviazione

Nella tabella seguente è descritto il modo in cui la compressione di riga influisce sui tipi esistenti in SQL Server e nel database SQL di Azure. Nella tabella non sono inclusi i risparmi in termini di spazio che possono essere ottenuti usando la compressione di pagina.

Tipo di dati Influenza sull'archiviazione Descrizione
tinyint No Lo spazio di archiviazione minimo necessario è 1 byte.
smallint Se il valore può essere archiviato in 1 byte, verrà utilizzato solo 1 byte.
int Utilizza solo i byte necessari. Ad esempio, se un valore può essere archiviato in 1 byte, verrà utilizzato solo 1 byte.
bigint Utilizza solo i byte necessari. Ad esempio, se un valore può essere archiviato in 1 byte, verrà utilizzato solo 1 byte.
decimal Usa solo i byte necessari, indipendentemente dalla precisione specificata. Ad esempio, se un valore può essere archiviato in 3 byte, verranno utilizzati solo 3 byte. Questo footprint di archiviazione corrisponde esattamente al formato di archiviazione vardecimal.
numeric Usa solo i byte necessari, indipendentemente dalla precisione specificata. Ad esempio, se un valore può essere archiviato in 3 byte, verranno utilizzati solo 3 byte. Questo footprint di archiviazione corrisponde esattamente al formato di archiviazione vardecimal.
bit L'overhead di metadati aumenta questo valore a 4 bit.
smallmoney Rappresenta i dati Integer utilizzando un numero intero di 4 byte. Il valore della valuta viene moltiplicato per 10.000 e il valore intero risultante viene archiviato rimuovendo tutte le cifre dopo il separatore decimale. e un'ottimizzazione dell'archiviazione analoga a quella associata ai tipi Integer.
money Rappresenta i dati Integer utilizzando un Integer a 8 byte. Il valore della valuta viene moltiplicato per 10.000 e il valore intero risultante viene archiviato rimuovendo tutte le cifre dopo il separatore decimale. A questo tipo sono associati un intervallo maggiore rispetto a smallmoney. e un'ottimizzazione dell'archiviazione analoga a quella associata ai tipi Integer.
float I byte meno significativi con zeri non sono archiviati. La compressionefloat si applica soprattutto per valori non frazionari in mantissa.
real I byte meno significativi con zeri non sono archiviati. La compressionereal si applica soprattutto per valori non frazionari in mantissa.
smalldatetime No Rappresenta i dati Integer usando due numeri interi a 2 byte ed è il numero di giorni da 1900-01-01. Non esiste alcun vantaggio per la compressione di riga per la parte relativa alla data di smalldatetime.

L'ora rappresenta il numero di minuti a partire dalla mezzanotte. Per i valori di ora appena successivi alle 04.00, viene utilizzato il secondo byte.

Se un tipo di smalldatetime viene usato solo per rappresentare una data (caso comune), l'ora è 0.0. La compressione consente di risparmiare 2 byte archiviando l'ora nel formato con byte più significativo per la compressione di riga.
datetime Rappresenta i dati Integer utilizzando due numeri interi di 4 byte. Il numero intero rappresenta il numero di giorni con data di base 1900-01-01. I primi 2 byte possono rappresentare gli anni fino al 2079. In questo caso la compressione consente di risparmiare sempre 2 byte fino a quella data. Ogni valore intero rappresenta 3,33 millisecondi. Poiché la compressione esaurisce i primi 2 byte nei i primi cinque minuti e deve utilizzare il quarto byte dopo le 16.00, a partire da tale ora è possibile risparmiare solo 1 byte in termini di spazio. Quando datetime viene compresso come qualsiasi altro numero intero, la compressione consente di risparmiare 2 byte nell'archiviazione della data.
date No Rappresenta i dati Integer usando 3 byte. In questo modo è possibile rappresentare la data a partire da 0001-01-01. Poiché per le date contemporanee la compressione di riga utilizza tutti i 3 byte, non viene ottenuto alcun risparmio in termini di spazio.
time No Rappresenta i dati Integer usando 3-6 byte. Sono disponibili diversi valori di precisione, da 0 a 9, rappresentabili con un numero di byte compreso tra 3 e 6. Lo spazio compresso viene utilizzato nel modo seguente:

Precisione = 0. Byte = 3. Ogni valore intero rappresenta un secondo. La compressione può rappresentare le ore fino alle 18.00 utilizzando 2 byte, con un risparmio potenziale di 1 byte.

Precisione = 1. Byte = 3. Ogni valore intero rappresenta 1/10 secondi. Poiché la compressione utilizza il terzo byte prima delle 02.00, il risparmio in termini di spazio è ridotto.

Precisione = 2. Byte = 3. Caso analogo al precedente. È improbabile ottenere un risparmio.

Precisione = 3. Byte = 4. Poiché i primi 3 byte vengono utilizzati prima delle 05.00, il risparmio ottenuto è ridotto.

Precisione = 4. Byte = 4. Poiché i primi 3 byte vengono utilizzati nei primi 27 secondi, non viene ottenuto alcun risparmio in termini di spazio.

Precisione = 5, Byte = 5. Il quinto byte verrà utilizzato dopo le 12.00.

Precisione = 6 e 7, Byte = 5. Non viene ottenuto alcun risparmio in termini di spazio.

Precisione = 8, Byte = 6. Il sesto byte verrà utilizzato dopo le 03.00.

La compressione di riga non apporta alcuna modifica all'archiviazione. In generale, se si comprime il tipo di dati time , non è possibile prevedere un risparmio significativo in termini di spazio.
datetime2 Rappresenta i dati Integer usando 6-9 byte. I primi 4 byte rappresentano la data. I byte utilizzati per rappresentare l'ora dipenderanno dalla precisione dell'ora specificata.

Il valore intero rappresenta il numero di giorni a partire da 0001-01-01. Il limite superiore è la data del 31/12/9999. Per rappresentare una data nell'anno 2005, la compressione utilizza 3 byte.

Non viene ottenuto alcun risparmio nella rappresentazione dell'ora, poiché è consentito l'utilizzo di un numero di byte compreso tra 2 e 4 per valori di precisione dell'ora diversi. Di conseguenza, per rappresentare l'ora con valore di precisione di un secondo, la compressione utilizza 2 byte e il secondo byte viene utilizzato dopo 255 secondi.
datetimeoffset Tipo simile a datetime2, a parte il fatto che in questo caso sono disponibili 2 byte per il fuso orario in formato (HH:mm).

Analogamente a datetime2, la compressione consente di risparmiare 2 byte.

Per i valori del fuso orario, il valore mm potrebbe essere uguale a 0 per la maggior parte dei casi. Di conseguenza, la compressione consente di risparmiare 1 byte.

La compressione di riga non apporta alcuna modifica all'archiviazione.
char I caratteri di riempimento finali vengono rimossi. Si noti che nel motore di database viene inserito lo stesso carattere di riempimento indipendentemente dalle regole di confronto utilizzate.
varchar No Nessun effetto.
Testo No Nessun effetto.
nchar 1 I caratteri di riempimento finali vengono rimossi. Si noti che nel motore di database viene inserito lo stesso carattere di riempimento indipendentemente dalle regole di confronto utilizzate.
nvarchar No 1 Nessun effetto.
ntext No Nessun effetto.
binary Gli zero finali vengono rimossi.
varbinary No Nessun effetto.
Immagine No Nessun effetto.
cursor No Nessun effetto.
timestamp / rowversion Rappresenta i dati Integer utilizzando 8 byte. È disponibile un contatore data e ora gestito per ogni database, il cui valore iniziale è pari a 0. È possibile comprimere questo tipo in modo analogo a qualsiasi altro valore intero.
sql_variant No Nessun effetto.
uniqueidentifier No Nessun effetto.
table No Nessun effetto.
xml No 2 Nessun effetto.
Tipi definiti dall'utente No Rappresentati internamente come varbinary.
FILESTREAM No Rappresentati internamente come varbinary.

1La compressione Unicode supporta i tipi di dati a lunghezza fissa nchar e nvarchar. I valori di dati archiviati all'esterno di righe o in colonne nvarchar(max) non sono compressi. La compressione Unicode non è supportata per i dati nvarchar(max) anche se archiviati nella riga.

2 I dati all’esterno di righe non vengono compressi quando si abilita la compressione dei dati. Ad esempio, un record XML di dimensioni superiori a 8.060 byte usa pagine esterne alle righe, che non sono compresse.