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 versionnement de ligne aux tables avec des déclencheurs après.
Cela est couvert par Paul White ici
La taille réelle des données stockées est sans importance - c'est la taille potentielle qui importe.
De même, si vous utilisez des tables optimisées en mémoire depuis 2016, il est possible d'utiliser des colonnes LOB ou des combinaisons de largeurs de colonnes qui pourraient potentiellement dépasser la limite en ligne mais avec une pénalité.
Les colonnes (Max) 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 colonnes de longueur variable les plus grandes hors ligne. Encore une fois, cela ne dépend pas de la quantité de données que vous stockez là-bas.
Cela peut avoir un grand effet négatif sur la consommation de mémoire et les performances
Un autre cas où la sur-déclaration des largeurs de colonnes peut faire une grande différence est si la table sera jamais traitée en utilisant SSIS. La mémoire allouée pour les colonnes de longueur variable (non BLOB) est fixée pour chaque ligne dans un arbre d'exécution et est conforme à la longueur maximale déclarée des colonnes, ce qui peut entraîner une utilisation inefficace des tampons mémoire (exemple). Bien que le développeur de package SSIS puisse déclarer une taille de colonne plus petite que la source, cette analyse est mieux réalisée à l'avance et appliquée là-bas.
Dans le moteur SQL Server lui-même, un cas similaire est que lors du calcul de l'allocation de mémoire pour les opérations de tri, SQL Server suppose que les colonnes varchar(x) consommeront en moyenne x/2 octets.
Si la plupart de vos colonnes varchar sont plus remplies que cela, cela peut conduire à ce que les opérations de tri débordent vers tempdb.
Dans votre cas, si vos colonnes varchar sont déclarées comme 8000 octets mais ont en réalité des contenus bien inférieurs, votre requête se verra allouer de la mémoire dont elle n'a pas besoin, ce qui est évidemment inefficace et peut entraîner des attentes pour les allocations mémoire.
Cela est abordé dans la Partie 2 du Webcast des Ateliers SQL 1 téléchargeable 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
7 votes
Imaginez essayer de faire rentrer un nom d'entreprise de 500 caractères sur une carte de visite... :)
2 votes
@OMG Poneys : chaque fois que je vois votre nom d'utilisateur, je ris. Maintenant, que disiez-vous? (Je rigole)
4 votes
@jcollum : SpaceMan Spiff aura toujours mon vote. Ce n'est pas vrai - n'importe Calvin & Hobbes fera l'affaire, mais surtout ceux concernant la sculpture de neige. Ou le tyrannosaure pilotant un F-14. Mais je m'égare...