Jedním z příkladů, kde to může být rozdíl, je to, že to může zabránit optimalizaci výkonu, která zabrání přidávání informací o verzích řádků do tabulek se spouštěči after.
Toto popisuje Paul White zde
Skutečná velikost uložených dat je nepodstatná – záleží na velikosti potenciálu.
Podobně, pokud se od roku 2016 používají tabulky optimalizované pro paměť, bylo možné používat sloupce LOB nebo kombinace šířek sloupců, které by mohly potenciálně překročit limit inrow, ale s penalizací.
Sloupce (Max) jsou vždy uloženy mimo řádek. U ostatních sloupců, pokud velikost datového řádku v definici tabulky může přesáhnout 8 060 bajtů, SQL Server posune největší sloupce s proměnnou délkou mimo řádek. Opět to nezávisí na množství dat, která tam ukládáte.
To může mít velký negativní vliv na spotřebu paměti a výkon
Dalším případem, kdy přílišná deklarace šířky sloupců může mít velký rozdíl, je to, zda bude tabulka někdy zpracována pomocí SSIS. Paměť alokovaná pro sloupce s proměnnou délkou (ne BLOB) je pevná pro každý řádek v prováděcím stromu a odpovídá deklarované maximální délce sloupců, což může vést k neefektivnímu využití vyrovnávací paměti (příklad). Přestože vývojář balíčku SSIS může deklarovat menší velikost sloupce, než je velikost zdroje, tuto analýzu je nejlepší provést předem a vynutit ji tam.
V samotném stroji SQL Server je podobný případ, kdy při výpočtu přidělení paměti pro alokaci pro SORT
operace SQL Server předpokládá, že varchar(x)
sloupce v průměru spotřebují x/2
bajtů.
Pokud je většina vašich varchar
sloupce jsou plnější, což může vést k sort
operace se přelévají do tempdb
.
Ve vašem případě, pokud váš varchar
sloupce jsou deklarovány jako 8000
bajtů, ale ve skutečnosti mají obsah mnohem menší než to, že vašemu dotazu bude přidělena paměť, kterou nepotřebuje, což je zjevně neefektivní a může to vést k čekání na přidělení paměti.
To je zahrnuto v části 2 SQL Workshops Webcast 1 ke stažení zde nebo níže.
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