sql >> Databasteknik >  >> RDS >> Sqlserver

Minska SQL Server-tabellfragmentering utan att lägga till/släppa ett klustrat index?

Problem

Låt oss få lite klarhet, eftersom detta är ett vanligt problem, ett allvarligt problem för alla företag som använder SQL Server.

Detta problem, och behovet av CREATE CLUSTERED INDEX, är missförstådda.

Håller med om att det är bättre att ha ett permanent Clustered Index än att inte ha ett. Men det är inte meningen, och det kommer att leda till en lång diskussion ändå, så låt oss lägga det åt sidan och fokusera på den postade frågan.

Poängen är att du har betydande fragmentering på Högen . Du fortsätter att kalla det ett "bord", men det finns inget sådant på den fysiska datalagrings- eller DataStructure-nivån. En tabell är ett logiskt koncept, inte ett fysiskt. Det är en samling fysiska datastrukturer. Samlingen är en av två möjligheter:

  • Hög
    plus alla icke-klustrade index
    plus text-/bildkedjor

  • eller ett klusterindex
    (eliminerar högen och ett Icke-klustrade index)
    plus alla icke-klustrade index
    plus text-/bildkedjor.

Högar blir svårt splittrade; ju mer insprängda (slumpmässiga) Infoga/Raderingar/Uppdateringar det finns, desto mer fragmentering.

Det finns inget sätt att rensa upp högen, som den är. MS tillhandahåller ingen anläggning (andra leverantörer gör det).

Lösning

Men vi vet att Create Clustered Index skriver om och ordnar om Heapen, helt och hållet. Metoden (inte ett trick) är därför att skapa ett klusterindex endast i syfte att defragmentera högen och släpp det efteråt. Du behöver ledigt utrymme i db för table_size x 1.25.

Medan du håller på, använd för all del FILLFACTOR för att minska framtiden splittring. Högen kommer då att ta mer tilldelat utrymme, vilket möjliggör framtida infogning, borttagning och radexpansion på grund av uppdateringar.

Obs

  1. Observera att det finns tre nivåer av Fragmentering; detta handlar endast om nivå III, fragmentering inom högen, som orsakas av Brist på ett klusterindex

  2. Som en separat uppgift, någon annan gång, kanske du vill överväga implementeringen av ett permanent Clustered Index, som eliminerar fragmentering helt och hållet ... men det är separat från det publicerade problemet.

Svar på kommentar

Inte riktigt. Jag skulle inte kalla det en "begränsning".

  1. Metoden jag har gett för att eliminera fragmenteringen i högen är att skapa ett klusterindex, och sedan släppa det. Dvs. tillfälligt, vars enda syfte är att korrigera Fragmenteringen.

  2. Att implementera ett Clustered Index på bordet (permanent) är en mycket bättre lösning, eftersom det minskar totalt Fragmentering (Datastrukturen kan fortfarande bli Fragmenterad, se detaljerad information i länkarna nedan), vilket är mycket mindre än Fragmenteringen som sker i en Heap.

    • Varje tabell i en relationsdatabas (förutom "pipe" eller "queue"-tabeller) bör ha ett Clustered Index, för att kunna dra fördel av dess olika fördelar.

    • Det klustrade indexet bör finnas på kolumner som distribuerar data (undvika INSERT-konflikter), aldrig indexeras på en monotont ökande kolumn, såsom Record ID , vilket garanterar en INSERT Hot Spot på den sista sidan.

I MS SQL och Sybase ASE finns det tre nivåer av fragmentering, och inom varje nivå, flera olika typer . Tänk på att när vi hanterar Fragmentering måste vi fokusera på DataStructures, inte på tabeller (en tabell är en samling av DataStructures, som förklarats ovan). Nivåerna är:

  • Nivå I • Extra-DataStructure
    Utanför den berörda datastrukturen, över eller inom databasen.

  • Nivå II • Datastruktur
    Inom den berörda datastrukturen, ovanstående sidor (över alla sidor)
    Detta är den nivå som oftast tas upp av DBA:er.

  • Nivå III • Sida
    Inom den berörda datastrukturen, inom sidorna

Dessa länkar ger fullständig information om Fragmentering. De är specifika för Sybase ASE, men på strukturell nivå gäller informationen för MS SQL.

Observera att metoden jag har angett är Level II, den korrigerar Nivå II och III Fragmentering.



  1. MYSQL OR vs IN prestanda

  2. MySQL Duplicate kolumnfel endast när frågan lindades som underfråga

  3. utvalda användare har mer än en distinkt post i mysql

  4. Bästa sättet att hämta liknande objekt från en MySQL-databas