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

SQL Server – Dissekere det interne af sp_spaceused

Denne artikel er et forsøg på at dissekere outputtet fra sp_spaceused gemt procedure.

Introduktion

Forståelse af databasebrugens interne elementer og væksttendenserne spiller en afgørende rolle i at definere den rigtige størrelse af databasen. sp_spaceused er sandsynligvis en administrators mest udbredte systemlagrede procedure til at finde den diskplads, der bruges af en database. Dette hjælper med at få et hurtigt indblik i databasebrugen. Statistikker. sp_spaceused bruges til at vise antallet af rækker, datastørrelsen, indeksstørrelsen, mængden af ​​brugt plads, ubrugt plads af hvert objekt og den ikke-allokerede størrelse af databasen. Selvom man ser på værdierne givet af sp_spaceused, bør man ikke tænke på at formindske databasen eller datafilen eller logfilen. Mange gange er vi uvidende om, hvad vi laver. Mange gange ved vi ikke, hvad der ville være eftervirkningerne af at udføre sådanne iboende ressourceoperationer. Outputtet fra sp_spaceused fortæller os meget om databasens aktuelle ydeevne. Deutildelte kolonnen og denubrugte kolonne fortælle os den ledige plads, der er tilbage på database- og tabelniveauerne.

Denne artikel overvejer:

  1. Et kig ind i sp_spaceused
  2. Indvirkningen af ​​indstillingen for automatisk vækst på kolonnerne, uallokerede og ubrugte
  3. Sådan finder du oplysninger om pladsforbruget på database- og instansniveauerne
  4. Måling af automatisk væksthændelser
  5. Sådan finder du mdf- og ldf-filstørrelserne
  6. Faktorer, der bestemmer databasens ydeevne
  7. Og mere...

Internals af sp_spaceused

Fang detaljer om pladsforbrug for alle tabellerne

I nedenstående T-SQL bruges den udokumenterede lagrede procedure sp_MSforeachtable til at krydse alle tabellerne inden for rammerne af den aktuelle databasekontekst for at få pladsforbrugsmetrikken for alle tabellerne i konteksten.

Erklær @tbl_sp_spaceused table( navn varchar(100) NULL, rækker bigint NULL, reserveret varchar(20) NULL, data varchar(20) NULL, index_size varchar(20) NULL, ubrugt varchar(20) NULL )-- indsæt output af sp_spaceused til tabelvariabelINSERT INTO @tbl_sp_spaceused (navn, rækker, reserveret, data, index_size, unused )EXEC sp_MSforeachtable @command1 ='EXEC sp_spaceused [?]'VÆLG *FRA @tbl_sp_spaceusedorder efter rækker desc

Fang oplysninger om pladsforbrug for alle databaser

Den udokumenterede lagrede procedure sp_MSforeachDB bruges til at krydse hele databasen inden for rammerne af den aktuelle SQL-instans for at få oplysninger om pladsforbruget for alle databaserne.

erklær @tbl_sp_spaceusedDBs tabel( databasenavn varchar(100) NOT NULL, database_size varchar(50) NULL, ikke-allokeret varchar(30) NULL, reserveret varchar(20) NULL, data varchar(20) NULL, index_size varchar(20) NULL , ubrugt varchar(20) NULL )INSERT INTO @tbl_sp_spaceusedDBs (database_name, database_size, unallocated, reserved, data, index_size, unused )EXEC sp_msforeachdb @command1="brug ? exec sp_spaceused @oneresultset_space @oneresultset_space @oneresultset_SELECT_ database_size

Her databasenavn er navnet på databasen; i dette tilfælde PythonSample . databasestørrelse er Uallokeret+Reserveret+Data+Index+Uused =MDF +LDF (=848 MB i dette tilfælde). Deutildelte pladsen her er 51,94 MB.

Dette er i virkeligheden diskgrænsen, der er blevet markeret for databasen. Sp_spaceused udsender ikke-allokeret kolonne defineret på databaseniveau, og den er ikke reserveret til nogen tabel og kan tages af det første objekt, der hævder mere plads til at vokse.

De ikke-allokerede plads er den ledige plads inde i datafilen, så den ikke behøver at vokse automatisk hver gang du udsteder en forespørgsel; Normalt styrer SQL Server Storage Engine autovæksten ved hjælp af en mekanisme kendt som Proportional Fill Algorithm. Styringen af ​​omfanget sker effektivt baseret på antallet af skrivninger, der sker på filerne. Og på samme tid, når den brugte plads når en tærskel, udløses en hændelse for yderligere autovækst. Indstilling af den rigtige værdi af ikke-allokeret plads afhænger af behovene og situationerne og arten af ​​brugen af ​​databasen. Ikke-allokeret plads er den plads, der endnu ikke er i brug, og som er "up for grabs". I det væsentlige er disse udstrækninger markeret med bit 1 på GAM-siden. Når man forstår konceptet med autovækst fra oven, kan enhver form for vækst generere yderligere ikke-allokerede omfang.

Ved hjælp af følgende SQL-forespørgsel kan vi se antallet af gange, hvor automatisk væksthændelse blev genereret, sammen med den tid, databasen har holdt i venteposition for processen.

DECLARE @fname NVARCHAR(1000);-- Hent navnet på den aktuelle standard traceSELECT @fname =CAST(værdi SOM VARCHAR(MAX))FROM ::fn_trace_getinfo(DEFAULT)WHERE traceid =1 OG egenskab =2;SELECT ft.StartTime [Start Time] ,t.name [Begivenhedsnavn] ,DB_NAME(ft.databaseid) [Databasenavn] ,ft.Filename [Filnavn] ,(ft.IntegerData*8)/1024.0 [Vækst MB] ,( ft.duration/1000) [Varighed MS]FRA ::fn_trace_gettable(@fname, DEFAULT) AS ft INNER JOIN sys.trace_events AS t ON ft.EventClass =t.trace_event_id WHERE (ft.EventClass =92 -- DateFile Auto-growthFile ELLER ft.EventClass =93) -- LogFile Auto-growthORDER BY ft.StartTime

Lad os se på, hvad hvert af begreberne betyder:

Reserveret :Den plads, der er reserveret til brug af databaseobjekter =(Data +Indeks + Ubrugt ) =476704 + 1280 + 1312 =479296 KB. Dette angiver, hvor fyldte objekterne er; ideelt set forventes 10 % af ubrugt plads til transaktionstabeller.

Data :Den faktiske størrelse af dataene. Dette er summen af ​​alle databasens datafiler.

Indeks :Mængden af ​​plads, der bruges af indekset.

Bemærk:I nogle tilfælde har jeg set, at størrelsen af ​​indeksstørrelsen er større end størrelsen af ​​faktiske data. For så vidt angår indekser, er det, der er nødvendigt for systemet, altid afhængigt af databasens ydeevne. Mange gange er læseoperationerne vigtigere end skriveoperationerne. Og i nogle andre tilfælde er skrivning vigtigere end læsninger. I tilfælde, hvor virksomheden har besluttet, at læsning er langt vigtigere end skrivning, kan det system have brug for tonsvis af indekser for at tilfredsstille virksomhedens og brugernes præstationskrav.

Ubrugt :En del af den reserverede plads, som endnu ikke er brugt

Ubrugte er sider på tildelte områder, men er endnu ikke brugt af noget objekt. Så snart et omfang er tildelt (enten som ensartet eller et fælles omfang), får vi otte reserverede sider på det omfang. Nogle sider er brugt, og nogle er ubrugte.

Den ubrugte og ikke-allokeret kolonner i outputtet kan være forvirrende. For at præcisere den ubrugte kolonneoutput viser ikke mængden af ​​ledig plads tilbage i hele databasen. Det er i stedet den samlede mængde plads, der er reserveret til tabeller, men ikke fyldt med data. I mange tilfælde kan den ubrugte plads genvindes ved at oprette et klynget indeks eller administrere de eksisterende indekser.

Outputtet af sp_spaceused kan yderligere forenkles for at finde størrelsen på .mdf-filen og .log-filerne. Summen af ​​den reserverede plads og den ikke-allokerede plads er mere eller mindre lig med størrelsen af ​​data-eller MDF-filen. Hvis du trækker MDF-filstørrelsen fra databasestørrelsen, får du også logfilens størrelse.

Så her er to formler:

MDF-filens størrelse =reserveret + ikke-allokeret plads

Logfilens størrelse =Database_Size – MDF-filstørrelse

VÆLG 476704+ 1280+ 1312 'Reserveret KB', (479296/1024.00)+51.94 'MDFSizeMB', 848.00 - ((479296/1024.00)+51.94) 'LogSizeMB' 

De førnævnte punkter fortæller os, hvordan hver af kolonnerne i outputtet af sp_spaceused fortolkes, beregnes og analyseres.

Konsekvensen af ​​indstillingen for automatisk vækst

De oprindelige størrelser og konfigurationen af ​​automatisk vækst har en betydelig effekt på den uudnyttede plads. At sætte de rigtige værdier for disse er en udfordring. Jeg har set mange tilfælde, hvor autovæksten var sat til at vokse i procent. Lad os antage, at autovæksten er sat til 25% for en datafilstørrelse på 100 GB. Det kræver kun 4 automatisk væksthændelser at fylde diskdrevet.

Den anden sag er at genopbygge indekserne. Denne operation har en direkte indvirkning på den ubrugte plads i bordet, da dataene omrokeres mellem ensartet og blandet omfang. I få tilfælde, mens du omrokerer siderne, kan handlingen inducere ikke-allokeret plads på grund af indstillingen for automatisk vækst af datafilen.

Lad os overveje et scenario, hvor indstillingen for automatisk vækst ikke er korrekt indstillet på databasen. Dette er igen et problem:Hvis automatisk vækst er aktiveret på databasen, betyder det, at drevudvidelsen finder sted automatisk under en eller anden begivenhed, selvom dataene ikke bruger al pladsen.

Det er altid en god praksis at indstille den passende automatiske vækstindstilling for datafilen. Nogle gange kan den forkerte indstilling af datafilen injicere fysisk fragmentering, hvilket resulterer i alvorlig ydeevneforringelse af systemet. Med andre ord, hvis du ikke har ikke-allokeret plads, vil de nye data forsøge at sidde på tomme steder, der kan være spredt. Dette gælder også for logfilen. Den ikke-allokerede plads i databasen påvirker indirekte indstillingen for automatisk vækst af datafilen og logfilen og påvirker direkte ydeevnen. Det vigtigste er at finde den rigtige balance.

Afslutning

  1. I processen med at oprette databasen er den definerede størrelse (dvs. den oprindelige størrelse) intet andet end databasens faktiske størrelse. Denne oprindelige størrelse registreres i sidehovedet. Under en databaseformindskelsesproces bruger processen minimumsstørrelsen egenskab som reference, kun hvis den faktiske datastørrelse er mindre end minimumsstørrelsen - minimumsstørrelsen findes også i sidehovedet og kan ses ved hjælp af kommandoen DBCC PAGE. Den samme proces gælder også for DBCC SHRINKFILE, som krymper filer til mindre end deres oprindelige størrelser.
  2. Det er ikke en anbefalet praksis at formindske databasen for at frigøre drevplads, selvom beslutningen afhænger af scenariet – usædvanlige scenarier kan berettige en ukonventionel handling. Man skal dog huske, at krympning af en database introducerer fragmentering i databasen. Det er altid en god praksis at analysere årsagen til den ikke-allokerede plads og ubrugt plads af genstandene. I mange tilfælde vil det være en levedygtig/anbefalet mulighed at udvide disken for at håndtere datavæksten.
  3. Konfiguration af automatisk vækst:Når SQL Server udfører en automatisk vækst-operation, skal transaktionen, der udløste auto-grow-hændelsen, vente, indtil auto-grow-hændelsen er fuldført. Først derefter kan selve transaktionen gennemføres.
  4. Det anbefales altid at indstille mulighederne for automatisk vækst i tal i stedet for i procenter.
  5. Induktionen af ​​ubrugt plads i tabellen kan skyldes følgende årsager:
    • Fragmentering
      Når data er fragmenteret på grund af deres art og definitionstype, genereres der noget ubrugt plads. En hyppig ændring af dataene (Alle OPDATERING, INSERT ELLER SLET-operationer) fører også til flere sideopdelinger, hvilket er mere tilbøjeligt til at generere ubrugt plads i tabellen.
    • Intet klynget indeks på bordet
      For at reducere fragmentering i en heap kan man tænke på at oprette et klynget indeks på bordet. For at reducere indeksfragmentering skal du udføre indeksvedligeholdelse ved at bestemme avg_fragmentation_in_percent-værdien.
    • Størrelse på data
      I nogle tilfælde giver brug af passende datatyper mindre datarækker, som igen gør det muligt at placere flere rækker på en side. Det reducerer ikke kun den interne ubrugte plads, men har også en indvirkning på ydeevnen ved at reducere antallet af sideopdelinger.
  6. Den ubrugte plads kan også være et resultat af at droppe kolonnen med variabel længde. Brug DBCC CLEANTABLE, efter du har foretaget væsentlige ændringer i kolonnerne med variabel længde i en tabel eller indekseret visning for straks at genvinde den ubrugte plads. Alternativt kan du genopbygge indekserne på tabellen eller visningen; dette er dog en mere ressourcekrævende operation.
  7. Den ubrugte plads er relativt større, når vi ender med at indlæse relativt større data (>8 KB). I sådanne tilfælde ender vi med store mængder ubrugt plads på datasiderne.
  8. Efter en SharePoint-migrering kan man se en betydelig mængde af den ubrugte plads introduceret i databaserne. Genvindingen er en langsommere proces, spøgelsesoprydningsprocessen fjerner disse sider, og frigørelsen sker over en periode.
  9. I nogle tilfælde er værdierne af sp_spaceused muligvis ikke korrekte. Selvom sp_spaceused får sin information fra systemobjektet, som indeholder alle estimaterne, kan det nogle gange være unøjagtigt. En af grundene til dette er, at under en databasemigrering, eller i tilfælde af forældede statistikker, eller når systemet gennemgår hyppige DDL-modifikationer, eller efter at have udført store bulk-kopieringsoperationer. For at synkronisere systemobjekter skal du bruge DBCC updateusage(0)- eller DBCC CHECKTABLE-sætningerne for at sikre, at sp_spaceused returnerer opdaterede nøjagtige data. Husk dog, at DBCC-kommandoer er ressourcekrævende; have en god forståelse for implikationen af ​​dets brug. Når vi udfører kommandoen DBCC updateusage, scanner SQL Server Database Engine datasiderne i databasen og foretager nødvendige rettelser tilsys.allocation_units og sys.partitions katalogvisninger vedrørende den lagerplads, der bruges af hver tabel.

Referencer

  • https://msdn.microsoft.com/en-us/library/cc280360.aspx
  • https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-cleantable-transact-sql
  • https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-database-files-transact-sql

  1. Spørgsmål til Oracle Interview

  2. Udtræk ugenummeret fra en dato i SQL Server (T-SQL)

  3. SQL Server VIS TABELLER Tilsvarende

  4. Sådan overføres en null-variabel til en SQL Stored Procedure fra C#.net-kode