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

SQL Server Maksimal rækkestørrelse vs Varchar(Max) størrelse

I Microsoft SQL Server er data (som inkluderer indekser) gemt på en eller flere 8k (8192 bytes) "sider". Der er forskellige typer sider, der kan bruges til at håndtere forskellige situationer (f.eks. Data, LOB, Index, AllocationMap osv.) Hver side har en header, som er metadata om den side og hvad den indeholder.

De fleste data er gemt i selve rækken, og en eller flere af disse rækker bliver igen gemt på en side for "in-row data". På grund af den plads, som rækkeoverskriften tager, er den største en række kan være (for "in-row"-data) 8060 bytes.

Det er dog ikke alle data, der er gemt i rækken. For visse datatyper kan dataene faktisk gemmes på en "LOB-data"-side, mens en markør er tilbage i "in-row"-dataene:

  • Ældre/forældede LOB-typer, som ingen længere burde bruge (TEXT , NTEXT og IMAGE ), gemmer som standard altid deres data på LOB-sider og brug altid en 16-byte pointer til den pågældende LOB-side.

  • De nyere LOB-typer (VARCHAR(MAX) , NVARCHAR(MAX) , VARBINARY(MAX) og XML ), vil som standard forsøge at passe dataene direkte i rækken, hvis det passer. Ellers gemmer den dataene på LOB-sider og bruger en pointer på 24 - 72 bytes (afhængigt af størrelsen af ​​LOB-dataene).

Sådan kan du gemme op til 78 GB + 4 bytes (kan ikke glemme INT Primær nøgle;-) i en enkelt række:den maksimale rækkestørrelse vil være mellem 940 bytes ((39 * 24) + 4) og 2812 bytes ((39 * 72) + 4). Men igen, det er bare den maksimale rækkevidde; hvis dataene i hver af de 39 VARCHAR(MAX) felter er kun 10 bytes, så vil alle data blive gemt i rækken, og rækkestørrelsen vil være 394 bytes ((39 * 10) + 4).

I betragtning af at du har så mange felter med variabel længde (uanset om de er MAX eller ej), er den eneste måde at estimere størrelsen af ​​fremtidige rækker på at have en god idé om, hvilke data du vil gemme i denne tabel. Selvom en tabel med alle, eller endda det meste, MAX-datatyper indebærer, at ingen rigtig har nogen idé om, hvad der vil blive gemt i denne tabel.

I den retning skal det påpeges, at dette er en forfærdeligt modelleret tabel / forfærdelig brug af MAX datatypefelter, og bør refaktoriseres.

For flere detaljer om, hvordan datasider er struktureret, se venligst mit svar på følgende DBA.StackExchange-spørgsmål:

SUM af DATALENGTH'er matcher ikke tabelstørrelse fra sys.allocation_units



  1. Hvordan håndteres InnoDB-deadlocks korrekt i Java/JDBC?

  2. Skinner 5:grupper poster efter DateTime-feltet i trævisning

  3. Hvordan sender man data til to tabeller med samme bruger-id som primærnøgle?

  4. Slet sætning i SQL er meget langsom