sql >> Database teknologi >  >> RDS >> Sqlserver

er der en fordel ved varchar(500) frem for varchar(8000)?

Et eksempel, hvor dette kan gøre en forskel, er, at det kan forhindre en ydeevneoptimering, der undgår at tilføje rækkeversionsinformation til tabeller med efter-triggere.

Dette er dækket af Paul White her

Den faktiske størrelse af de lagrede data er ligegyldig – det er potentialstørrelsen, der betyder noget.

På samme måde, hvis du bruger hukommelsesoptimerede tabeller siden 2016, har det været muligt at bruge LOB-kolonner eller kombinationer af kolonnebredder, der potentielt kunne overskride inrow-grænsen, men med en straf.

(Maks.) kolonner gemmes altid uden for rækken. For andre kolonner, hvis datarækkestørrelsen i tabeldefinitionen kan overstige 8.060 bytes, skubber SQL Server største kolonne(r) med variabel længde ud af rækken. Igen, det afhænger ikke af mængden af ​​de data, du gemmer der.

Dette kan have en stor negativ effekt på hukommelsesforbrug og ydeevne

Et andet tilfælde, hvor overdeklarering af kolonnebredder kan gøre en stor forskel, er, om tabellen nogensinde vil blive behandlet ved hjælp af SSIS. Hukommelsen tildelt til kolonner med variabel længde (ikke BLOB) er fastsat for hver række i et udførelsestræ og er i henhold til kolonnernes erklærede maksimale længde, hvilket kan føre til ineffektiv brug af hukommelsesbuffere (eksempel). Selvom SSIS-pakkeudvikleren kan erklære en mindre kolonnestørrelse end kilden, udføres denne analyse bedst på forhånd og håndhæves der.

Tilbage i selve SQL Server-motoren er et lignende tilfælde, at når man beregner hukommelsesbevillingen til at allokere til SORT operationer SQL Server antager, at varchar(x) kolonner vil i gennemsnit forbruge x/2 bytes.

Hvis de fleste af dine varchar kolonner er fyldigere, end det kan føre til sort operationer, der løber til tempdb .

I dit tilfælde, hvis din varchar kolonner erklæres som 8000 bytes, men har faktisk meget mindre indhold end det, din forespørgsel vil få tildelt hukommelse, som den ikke kræver, hvilket åbenlyst er ineffektivt og kan føre til ventetid på hukommelsesbevillinger.

Dette er dækket i del 2 af SQL Workshops Webcast 1, der kan downloades herfra eller se nedenfor.

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



  1. Hvordan læser og opdaterer jeg SQLite-database ved hjælp af ListView i Android?

  2. Ikke ubetydelig forskel i eksekveringsplanen med Oracle ved brug af jdbc Tidsstempel eller Dato

  3. uløst reference til objekt [INFORMATION_SCHEMA].[TABLER]

  4. Tilfældig værdi for kolonnen DATETIME