Un exemple où cela peut faire une différence est que cela peut empêcher une optimisation des performances qui évite d'ajouter des informations de version de ligne aux tables avec des déclencheurs after.
Ceci est couvert par SQL Kiwi ici
La taille réelle des données stockées n'a pas d'importance - c'est la taille potentielle qui compte.
De même, si vous utilisez des tables à mémoire optimisée depuis 2016, il est possible d'utiliser des colonnes LOB ou des combinaisons de largeurs de colonne qui pourraient potentiellement dépasser la limite d'entrée, mais avec une pénalité.
(Max) les colonnes sont toujours stockées hors ligne. Pour les autres colonnes, si la taille de ligne de données dans la définition de table peut dépasser 8 060 octets, SQL Server déplace la ou les plus grandes colonnes de longueur variable hors ligne. Encore une fois, cela ne dépend pas de la quantité de données que vous y stockez.
Cela peut avoir un effet négatif important sur la consommation de mémoire et les performances
Un autre cas où la surdéclaration des largeurs de colonne peut faire une grande différence est si la table sera un jour traitée à l'aide de SSIS. La mémoire allouée pour les colonnes de longueur variable (non BLOB) est fixe pour chaque ligne dans un arbre d'exécution et correspond à la longueur maximale déclarée des colonnes, ce qui peut conduire à une utilisation inefficace des tampons mémoire (exemple) . Bien que le développeur du package SSIS puisse déclarer une taille de colonne plus petite que la source, cette analyse est mieux effectuée à l'avance et appliquée à cet endroit.
De retour dans le moteur SQL Server lui-même, un cas similaire est celui lors du calcul de l'allocation de mémoire à allouer pour les SORT
opérations, SQL Server suppose que les varchar(x)
colonnes consommeront en moyenne des x/2
octets.
Si la plupart de vos varchar
colonnes sont plus pleines que cela, cela peut entraîner des sort
débordements d'opérations tempdb
.
Dans votre cas, si vos varchar
colonnes sont déclarées sous forme d' 8000
octets mais ont en fait un contenu beaucoup moins important que cela, votre requête se verra allouer de la mémoire dont elle n'a pas besoin, ce qui est évidemment inefficace et peut conduire à des attentes d'attribution de mémoire.
Ceci est couvert dans la partie 2 du Webcast 1 des ateliers SQL téléchargeable à partir d'ici ou voir ci-dessous.
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