Un esempio in cui questo può fare la differenza è che può impedire un'ottimizzazione delle prestazioni che evita di aggiungere informazioni sul controllo delle versioni delle righe alle tabelle con trigger after.
Questo è coperto da SQL Kiwi qui
La dimensione effettiva dei dati archiviati è irrilevante: è la dimensione potenziale che conta.
Allo stesso modo se si utilizzano tabelle ottimizzate per la memoria dal 2016 è stato possibile utilizzare colonne LOB o combinazioni di larghezze di colonna che potrebbero potenzialmente superare il limite di inrow ma con una penalità.
Le colonne (Max) vengono sempre memorizzate fuori riga. Per altre colonne, se la dimensione della riga di dati nella definizione della tabella può superare i 8.060 byte, SQL Server inserisce le colonne di lunghezza variabile più grandi fuori riga. Ancora una volta, non dipende dalla quantità di dati archiviati lì.
Ciò può avere un grande effetto negativo sul consumo di memoria e sulle prestazioni
Un altro caso in cui dichiarare eccessivamente le larghezze delle colonne può fare una grande differenza è se la tabella verrà mai elaborata utilizzando SSIS. La memoria allocata per le colonne a lunghezza variabile (non BLOB) è fissa per ogni riga in un albero di esecuzione ed è in base alla lunghezza massima dichiarata delle colonne, il che può portare a un utilizzo inefficiente dei buffer di memoria (esempio) . Sebbene lo sviluppatore del pacchetto SSIS possa dichiarare una dimensione della colonna inferiore rispetto alla fonte, questa analisi è meglio eseguire in anticipo e applicare lì.
Torna nel motore di SQL Server stesso un caso simile è che quando si calcola la concessione di memoria da allocare per le SORT
operazioni, SQL Server presuppone che le varchar(x)
colonne consumeranno in media x/2
byte.
Se la maggior parte delle tue varchar
colonne è più piena di quella, ciò può portare alla sort
fuoriuscita delle operazioni tempdb
.
Nel tuo caso, se le tue varchar
colonne sono dichiarate come 8000
byte ma in realtà hanno un contenuto molto inferiore a quello, alla tua query verrà allocata memoria che non richiede, il che è ovviamente inefficiente e può portare ad attese per concessioni di memoria.
Questo argomento è trattato nella Parte 2 del Webcast 1 dei workshop SQL scaricabile da qui o vedi sotto.
use tempdb;
CREATE TABLE T(
id INT IDENTITY(1,1) PRIMARY KEY,
number int,
name8000 VARCHAR(8000),
name500 VARCHAR(500))
INSERT INTO T
(number,name8000,name500)
SELECT number, name, name /*<--Same contents in both cols*/
FROM master..spt_values
SELECT id,name500
FROM T
ORDER BY number
SELECT id,name8000
FROM T
ORDER BY number