sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server – Dissekera internerna i sp_spaceused

Den här artikeln är ett försök att dissekera utdata från sp_spaceused lagrad procedur.

Introduktion

Att förstå databasanvändningens interna delar och tillväxttrenderna spelar en avgörande roll för att definiera rätt storlek på databasen. sp_spaceused är förmodligen en administratörs mest utförda systemlagrade procedur för att hitta det diskutrymme som används av en databas. Detta hjälper till att få en snabb inblick i databasanvändningen. statistik. sp_spaceused används för att visa antalet rader, datastorleken, indexstorleken, mängden använt utrymme, oanvänt utrymme för varje objekt och databasens icke-allokerade storlek. Även om man tittar på värdena som ges av sp_spaceused, bör man inte tänka på att krympa databasen eller datafilen eller loggfilen. Många gånger är vi omedvetna om vad vi gör. Många gånger vet vi inte vad som skulle bli följderna av att utföra sådana inbyggda resursoperationer. Utdata från sp_spaceused berättar mycket om databasens nuvarande prestanda. Denoallokerade kolumnen och oanvända talar om för oss det lediga utrymmet som finns kvar på databasen och tabellnivåerna.

Den här artikeln tar upp:

  1. En titt in i sp_spaceused
  2. Inverkan av inställningen för automatisk tillväxt på kolumnerna, oallokerade och oanvända
  3. Hitta information om utrymmesanvändning på databasen och instansnivåerna
  4. Mätning av automatisk tillväxthändelser
  5. Hitta mdf- och ldf-filstorlekarna
  6. Faktorer som avgör databasens prestanda
  7. Och mer...

Internal sp_spaceused

Fånga information om utrymmesanvändning för alla tabeller

I nedanstående T-SQL används den odokumenterade lagrade proceduren sp_MSforeachtable för att gå igenom alla tabeller inom ramen för den aktuella databaskontexten för att få utrymmesanvändningsmått för alla tabeller i sammanhanget.

Deklarera @tbl_sp_spaceused table( namn varchar(100) NULL, rader bigint NULL, reserverad varchar(20) NULL, data varchar(20) NULL, index_size varchar(20) NULL, oanvänd varchar(20) NULL )-- infoga utdata från sp_spaceused till tabellvariabelINSERT INTO @tbl_sp_spaceused (namn, rader, reserverad, data, index_size, oanvänd )EXEC sp_MSforeachtable @command1 ='EXEC sp_spaceused [?]'VÄLJ *FRÅN @tbl_sp_spaceusedorder efter rader desc

Fånga information om utrymmesanvändning för alla databaser

Den odokumenterade lagrade proceduren sp_MSforeachDB används för att gå igenom hela databasen inom ramen för den aktuella SQL-instansen för att få information om utrymmesanvändning för alla databaser.

declare @tbl_sp_spaceusedDBs table( database_name varchar(100) NOT NULL, database_size varchar(50) NULL, unallocated varchar(30) NULL, reserved varchar(20) NULL, data varchar(20) NULL, index_size varchar(20) NULL , oanvänd varchar(20) NULL )INSERT INTO @tbl_sp_spaceusedDBs ( databasnamn, databasstorlek, oallokerad, reserverad, data, index_storlek, oanvänd )EXEC sp_msforeachdb @command1="använd ? exec sp_spaceused @oneresultset_space @oneresultset_mellanslag @oneresultset_SELECT_databas @oneresultset_1" databasstorlek

Här, database_name är namnet på databasen; i det här fallet PythonSample . databasstorlek är Unallokerad+Reserverad+Data+Index+Uused =MDF +LDF (=848 MB i detta fall). Denoallokerade utrymmet här är 51,94 MB.

Detta är i själva verket diskgränsen som har markerats för databasen. Sp_spaceused matar ut oallokerad kolumn definierad på databasnivå och den är inte reserverad för någon tabell och kan tas av det första objektet som gör anspråk på mer utrymme att växa.

Den ej allokerade utrymme är det lediga utrymmet inuti datafilen så att den inte behöver växa automatiskt varje gång du skickar en fråga; vanligtvis hanterar SQL Server Storage Engine autotillväxten med hjälp av en mekanism som kallas Proportional Fill Algorithm. Hanteringen av omfattningarna görs effektivt baserat på antalet skrivningar som sker på filerna. Och samtidigt, när det använda utrymmet når en tröskel, utlöses en händelse för ytterligare autotillväxt. Att sätta rätt värde på otilldelat utrymme beror på behoven och situationerna samt typen av användning av databasen. Otilldelat utrymme är det utrymme som ännu inte är i bruk och som är "uppe att ta tag i". I huvudsak är dessa omfattningar markerade med bit 1 på GAM-sidan. Genom att förstå konceptet med autotillväxt från ovan, kan vilken typ av tillväxt som helst generera ytterligare otilldelade omfattningar.

Med hjälp av följande SQL-fråga kan vi se antalet gånger den automatiska tillväxthändelsen genererades, tillsammans med hur lång tid databasen har hållit på is för processen.

DECLARE @fname NVARCHAR(1000);-- Hämta namnet på det aktuella standardspåretVÄLJ @fname =CAST(värde SOM VARCHAR(MAX))FRÅN ::fn_trace_getinfo(DEFAULT)WHERE traceid =1 AND egenskap =2;SELECT ft.StartTime [Starttid] ,t.name [Händelsenamn] ,DB_NAME(ft.databaseid) [Databasnamn] ,ft.Filnamn [Filnamn] ,(ft.IntegerData*8)/1024.0 [Tillväxt MB] ,( ft.duration/1000) [Duration MS]FRÅN ::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

Låt oss titta på vad var och en av termerna betyder:

Reserverad :Utrymmet reserverat för användning av databasobjekt =(Data +Index + Oanvänd ) =476704 + 1280 + 1312 =479296 KB. Detta indikerar hur fulla objekten är; idealiskt förväntas 10 % av oanvänt utrymme för transaktionstabeller.

Data :Den faktiska storleken på data. Detta är summan av alla datafiler i databasen.

Index :Mängden utrymme som används av indexet.

Obs:I vissa fall har jag sett att storleken på indexstorleken är större än storleken på faktiska data. När det gäller index är vad som behövs för systemet alltid beroende av databasens prestanda. Många gånger är läsoperationerna viktigare än skrivoperationerna. Och i vissa andra fall är det viktigare att skriva än att läsa. I de fall där företaget har beslutat att läsning är mycket viktigare än att skriva, kan det systemet behöva massor av index för att tillfredsställa företagets och användarnas prestationskrav.

Oanvänd :En del av det reserverade utrymmet som ännu inte används

Oanvända är sidor på tilldelade omfattningar men används ännu inte av något objekt. Så fort en omfattning tilldelas (antingen som enhetlig eller delad omfattning) får vi åtta reserverade sidor på den omfattningen. Vissa sidor är använda och andra är oanvända.

Den oanvända och ej allokerad kolumner i utdata kan vara förvirrande. För att förtydliga, oanvända kolumnutdata visar inte mängden ledigt utrymme som finns kvar i hela databasen. Det är istället den totala mängden utrymme som är reserverat för tabeller men inte fyllt med data. I många fall kan det oanvända utrymmet återvinnas genom att skapa ett klustrat index eller hantera befintliga index.

Utdata från sp_spaceused kan ytterligare förenklas för att hitta storleken på .mdf-filen och .log-filerna. Summan av det reserverade utrymmet och det oallokerade utrymmet är mer eller mindre lika med storleken på data- eller MDF-filen. Om du subtraherar MDF-filstorleken från databasstorleken får du loggfilens storlek.

Så här är två formler:

MDF-filens storlek =reserverat + oallokerat utrymme

Storlek på loggfilen =Databas_Size – MDF-filstorlek

VÄLJ 476704+ 1280+ 1312 'Reserverad KB', (479296/1024.00)+51.94 'MDFSizeMB', 848.00 - ((479296/1024.00)+51.94) 'LogSizeMB' 

Ovannämnda punkter berättar hur var och en av kolumnerna i utdata från sp_spaceused tolkas, beräknas och analyseras.

Inverkan av inställningen för automatisk tillväxt

De ursprungliga storlekarna och konfigurationen för automatisk tillväxt har en betydande effekt på det oanvända utrymmet. Att sätta rätt värden för dessa är en utmaning. Jag har sett många fall där autotillväxten var inställd på att växa i procent. Låt oss anta att den automatiska tillväxten är inställd på 25% för en datafilstorlek på 100 GB. Det krävs bara fyra automatiska tillväxthändelser för att fylla hårddisken.

Det andra fallet är att bygga om indexen. Denna operation har en direkt inverkan på det oanvända utrymmet i tabellen, eftersom data blandas om mellan enhetlig och blandad omfattning. I några få fall, när sidorna blandas om, kan åtgärden inducera oallokerat utrymme på grund av inställningen för automatisk tillväxt av datafilen.

Låt oss överväga ett scenario där inställningen för automatisk tillväxt inte är korrekt inställd på databasen. Det här är återigen ett problem:Om automatisk tillväxt är aktiverad i databasen betyder det att enhetens expansion sker automatiskt under någon händelse även om data inte använder allt utrymme.

Det är alltid en bra praxis att ställa in lämplig inställning för automatisk tillväxt för datafilen. Ibland kan felaktig inställning av datafilen injicera fysisk fragmentering, vilket resulterar i allvarlig prestandaförsämring av systemet. Med andra ord, om du inte har oallokerat utrymme, kommer den nya datan att försöka sitta på tomma platser som kan vara utspridda. Detta gäller även loggfilen. Det oallokerade utrymmet i databasen påverkar indirekt inställningen för autotillväxt för datafilen och loggfilen och påverkar direkt prestandan. De viktigaste är att hitta rätt balans.

Avsluta

  1. I processen för att skapa databasen är den definierade storleken (dvs. den ursprungliga storleken) ingenting annat än databasens faktiska storlek. Denna initiala storlek registreras i sidhuvudet. Under en databaskrympningsprocess använder processen minimistorleken egenskapen som referens, endast om den faktiska datastorleken är mindre än minimistorleken – minimistorleken finns också i sidhuvudet och kan ses med kommandot DBCC PAGE. Samma process gäller även för DBCC SHRINKFILE, som krymper filer till mindre än deras ursprungliga storlek.
  2. Det rekommenderas inte att krympa databasen för att frigöra diskutrymme, även om beslutet beror på scenariot – ovanliga scenarier kan motivera en okonventionell åtgärd. Man måste dock komma ihåg att krympning av en databas introducerar fragmentering i databasen. Det är alltid en god praxis att analysera grundorsaken till det oallokerade utrymmet och oanvänt utrymme av föremålen. I många fall skulle det vara ett genomförbart/rekommenderat alternativ att utöka disken för att hantera datatillväxten.
  3. Konfiguration för automatisk tillväxt:När SQL Server utför en automatisk tillväxt-operation måste transaktionen som utlöste auto-grow-händelsen vänta tills auto-grow-händelsen slutförs. Först då kan själva transaktionen slutföras.
  4. Det rekommenderas alltid att ställa in alternativen för automatisk tillväxt i siffror istället för i procent.
  5. Induktionen av oanvänt utrymme i tabellen kan bero på följande orsaker:
    • Fragmentering
      När data är fragmenterad på grund av dess karaktär och typ av definition genereras en del oanvänt utrymme. Dessutom leder en frekvent modifiering av data (alla UPDATE-, INSERT ELLER DELETE-operationer) till fler siddelningar, vilket är mer sannolikt att generera oanvänt utrymme i tabellen.
    • Inget klustrat index på tabellen
      För att minska fragmenteringen i en Heap kan man tänka sig att skapa ett klustrat index på bordet. För att minska indexfragmenteringen, utför indexunderhåll genom att bestämma värdet avg_fragmentation_in_percent.
    • Storleken på data
      I vissa fall ger användning av lämpliga datatyper mindre datarader som i sin tur tillåter att fler rader placeras på en sida. Det minskar inte bara det interna oanvända utrymmet utan har också en inverkan på prestandan genom att minska antalet siddelningar.
  6. Det oanvända utrymmet kan också bero på att kolumnen med variabel längd släpps. Använd DBCC CLEANTABLE efter att du gjort betydande ändringar i kolumnerna med variabel längd i en tabell eller indexerad vy för att omedelbart återta det oanvända utrymmet. Alternativt kan du bygga om indexen på tabellen eller vyn; detta är dock en mer resurskrävande operation.
  7. Det oanvända utrymmet är relativt sett större när vi slutar med att ladda relativt större data (>8 KB). I sådana fall får vi stora mängder outnyttjat utrymme på datasidorna.
  8. Efter en SharePoint-migrering kan man se en betydande del av det oanvända utrymmet som introduceras i databaserna. Återvinningen är en långsammare process, spökrensningsprocessen tar bort dessa sidor och frigörandet sker under en viss tidsperiod.
  9. I vissa fall kanske värdena för sp_spaceused inte är korrekta. Även om sp_spaceused får sin information från systemobjektet som innehåller alla uppskattningar, kan den ibland vara felaktig. En av anledningarna till detta är att under en databasmigrering, eller i händelse av föråldrad statistik, eller när systemet genomgår frekventa DDL-modifieringar, eller efter att ha utfört stora bulkkopieringsoperationer. För att synkronisera systemobjekt, använd DBCC updateusage(0)- eller DBCC CHECKTABLE-satserna för att säkerställa att sp_spaceused returnerar aktuella korrekta data. Kom dock ihåg att DBCC-kommandon är resurskrävande; ha en god förståelse för innebörden av dess användning. När vi kör kommandot DBCC updateusage skannar SQL Server Database Engine datasidorna i databasen och gör nödvändiga korrigeringar avsys.allocation_units och sys.partitions katalogvyer angående lagringsutrymmet som används av varje tabell.

Referenser

  • 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. java.lang.NoSuchFieldError:NONE i viloläge med Spring 3, maven, JPA, c3p0

  2. Inget sådant kolumn sqlite undantag

  3. Rails, MySQL och Snow Leopard

  4. ListAGG i SQLSERVER