Dit artikel is een poging om de uitvoer van de sp_spaceused . te ontleden opgeslagen procedure.
Inleiding
Inzicht in het interne gebruik van de database en de groeitrends spelen een cruciale rol bij het bepalen van de juiste omvang van de database. sp_spaceused is waarschijnlijk de meest uitgevoerde systeem opgeslagen procedure van een beheerder om de schijfruimte te vinden die door een database wordt gebruikt. Dit helpt om snel een glimp op te vangen van het databasegebruik. statistieken. sp_spaceused wordt gebruikt om het aantal rijen, de gegevensgrootte, indexgrootte, hoeveelheid gebruikte ruimte, ongebruikte ruimte door elk object en de niet-toegewezen grootte van de database weer te geven. Hoewel we kijken naar de waarden die worden gegeven door sp_spaceused, moet men er niet aan denken om de database of het gegevensbestand of het logbestand te verkleinen. Vaak zijn we ons niet bewust van wat we doen. Vaak weten we niet wat de nawerkingen zouden zijn van het uitvoeren van dergelijke intrinsieke bewerkingen van hulpbronnen. De uitvoer van sp_spaceused vertelt ons veel over de huidige prestaties van de database. De niet-toegewezen kolom en de ongebruikte kolom vertel ons de vrije ruimte in de database en de tabelniveaus.
Dit artikel beschouwt:
- Een kijkje in sp_spaceused
- Impact van de instelling voor automatische groei op de kolommen, niet-toegewezen en ongebruikt
- De details van het ruimtegebruik vinden in de database en de instantieniveaus
- De automatische groeigebeurtenissen meten
- De mdf- en ldf-bestandsgroottes vinden
- Factoren die de prestaties van de database bepalen
- En meer...
Internals van sp_spaceused
Vastleg details over het ruimtegebruik van alle tabellen
In de onderstaande T-SQL wordt de ongedocumenteerde opgeslagen procedure sp_MSforeachtable gebruikt om alle tabellen binnen het bereik van de huidige databasecontext te doorkruisen om de ruimtegebruiksstatistieken van alle tabellen in de context te krijgen.
Declare @tbl_sp_spaceused table( name varchar(100) NULL, rows bigint NULL, reserved varchar(20) NULL, data varchar(20) NULL, index_size varchar(20) NULL, unused varchar(20) NULL ) -- insert output of sp_spaceused to table variable INSERT INTO @tbl_sp_spaceused ( name, rows, reserved, data, index_size, unused ) EXEC sp_MSforeachtable @command1 = 'EXEC sp_spaceused [?]' SELECT * FROM @tbl_sp_spaceused order by rows desc
Vast ruimtegebruiksdetails van alle databases vast
De ongedocumenteerde opgeslagen procedure sp_MSforeachDB wordt gebruikt om de hele database binnen het bereik van de huidige SQL-instantie te doorkruisen om de informatie over het ruimtegebruik van alle databases te krijgen.
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, unused varchar(20) NULL ) INSERT INTO @tbl_sp_spaceusedDBs ( database_name, database_size, unallocated, reserved, data, index_size, unused ) EXEC sp_msforeachdb @command1="use ? exec sp_spaceused @oneresultset = 1" SELECT * FROM @tbl_sp_spaceusedDBs ORDER BY database_name, database_size
Hier, database_name is de naam van de database; in dit geval PythonSample . database_size is de Utoegewezen+Gereserveerd+Data+Index+Ongebruikt =MDF +LDF (=848 MB in dit geval). De niet-toegewezen ruimte hier is 51,94 MB.
Dit is in werkelijkheid de schijfgrens die is gemarkeerd voor de database. De sp_spaceused voert een niet-toegewezen kolom uit die is gedefinieerd op databaseniveau en is niet gereserveerd voor een tabel en kan worden ingenomen door het eerste object dat meer ruimte claimt om te groeien.
De niet-toegewezen ruimte is de vrije ruimte in het gegevensbestand, zodat het niet automatisch hoeft te groeien telkens wanneer u een vraag stelt; meestal beheert de SQL Server Storage Engine de autogrowth met behulp van een mechanisme dat bekend staat als Proportional Fill Algorithm. Het beheer van de extensies wordt effectief gedaan op basis van het aantal schrijfbewerkingen op de bestanden. En tegelijkertijd, wanneer de gebruikte ruimte een drempel bereikt, wordt er een gebeurtenis geactiveerd voor verdere automatische groei. Het instellen van de juiste waarde van niet-toegewezen ruimte hangt af van de behoeften en situaties en de aard van het gebruik van de database. Niet-toegewezen ruimte is de ruimte die nog niet in gebruik is en "voor het grijpen" ligt. In wezen zijn deze extensies gemarkeerd met bit 1 op de GAM-pagina. Als we het concept van autogroei van bovenaf begrijpen, kan elk type groei verdere niet-toegewezen omvang genereren.
Met behulp van de volgende SQL-query kunnen we het aantal keren zien dat de auto-growth-gebeurtenis is gegenereerd, samen met de hoeveelheid tijd die de database heeft vastgehouden voor het proces.
DECLARE @fname NVARCHAR(1000); -- Get the name of the current default trace SELECT @fname = CAST(value AS VARCHAR(MAX)) FROM ::fn_trace_getinfo(DEFAULT) WHERE traceid = 1 AND property = 2; SELECT ft.StartTime [Start Time] ,t.name [Event Name] ,DB_NAME(ft.databaseid) [Database Name] ,ft.Filename [File Name] ,(ft.IntegerData*8)/1024.0 [Growth MB] ,(ft.duration/1000) [Duration MS] FROM ::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-growth OR ft.EventClass = 93) -- LogFile Auto-growth ORDER BY ft.StartTime
Laten we eens kijken wat elk van de termen betekent:
Gereserveerd :De ruimte gereserveerd voor gebruik door database-objecten =(Data +Index + Unused ) =476704 + 1280 + 1312 =479296 KB. Dit geeft aan hoe vol de objecten zijn; idealiter wordt 10% van de ongebruikte ruimte verwacht voor transactietabellen.
Gegevens :De werkelijke grootte van de gegevens. Dit is de som van alle gegevensbestanden van de database.
Index :De hoeveelheid ruimte die door de index wordt gebruikt.
Opmerking:in sommige gevallen heb ik gezien dat de grootte van de index groter is dan de grootte van de werkelijke gegevens. Wat indexen betreft, is wat nodig is voor het systeem altijd afhankelijk van de prestaties van de database. Vaak zijn de leesbewerkingen belangrijker dan de schrijfbewerkingen. En in sommige andere gevallen zijn schrijven belangrijker dan lezen. In gevallen waarin het bedrijf heeft besloten dat lezen veel belangrijker is dan schrijven, heeft dat systeem mogelijk tonnen indexen nodig om te voldoen aan de prestatie-eisen van het bedrijf en de gebruikers.
Ongebruikt :Een deel van de gereserveerde ruimte dat nog niet wordt gebruikt
Ongebruikt zijn pagina's op toegewezen gebieden, maar worden nog door geen enkel object gebruikt. Zodra een omvang is toegewezen (hetzij als een uniforme of een gedeelde omvang), krijgen we acht gereserveerde pagina's over die omvang. Sommige pagina's worden gebruikt en sommige zijn ongebruikt.
De ongebruikte en niet-toegewezen kolommen in de uitvoer kunnen verwarrend zijn. Ter verduidelijking:de ongebruikte kolomuitvoer toont niet de hoeveelheid vrije ruimte die nog over is in de hele database. Het is in plaats daarvan de totale hoeveelheid ruimte die is gereserveerd voor tabellen, maar niet is gevuld met gegevens. In veel gevallen kan de ongebruikte ruimte worden teruggewonnen door een geclusterde index te maken of de bestaande indexen te beheren.
De uitvoer van sp_spaceused kan verder worden vereenvoudigd om de grootte van het .mdf-bestand en .log-bestanden te vinden. De som van de gereserveerde ruimte en niet-toegewezen ruimte is min of meer gelijk aan de grootte van het gegevens- of MDF-bestand. Ook het aftrekken van de MDF-bestandsgrootte van de databasegrootte geeft de logbestandsgrootte.
Dus hier zijn twee formules:
Grootte van het MDF-bestand =gereserveerd + niet-toegewezen ruimte
Grootte van het logbestand =Database_Size – MDF-bestandsgrootte
SELECT 476704+ 1280+ 1312 'Reserved KB', (479296/1024.00)+51.94 'MDFSizeMB', 848.00 - ((479296/1024.00)+51.94) 'LogSizeMB'
De bovengenoemde punten vertellen ons hoe elk van de kolommen in de uitvoer van sp_spaceused wordt geïnterpreteerd, berekend en geanalyseerd.
Impact van instelling voor automatische groei
De initiële maten en de auto-groeiconfiguratie hebben een significant effect op de ongebruikte ruimte. Het instellen van de juiste waarden hiervoor is een uitdaging. Ik heb veel gevallen gezien waarin de automatische groei procentueel zou groeien. Laten we aannemen dat de automatische groei is ingesteld op 25% voor een gegevensbestandsgrootte van 100 GB. Er zijn slechts 4 auto-growth events nodig om de diskdrive te vullen.
Het andere geval is het opnieuw opbouwen van de indexen. Deze bewerking heeft een directe invloed op de ongebruikte ruimte van de tabel, omdat de gegevens opnieuw worden geschud tussen de uniforme en gemengde begrenzingen. In enkele gevallen kan de bewerking tijdens het herschikken van de pagina's niet-toegewezen ruimte veroorzaken vanwege de instelling voor automatisch groeien van het gegevensbestand.
Laten we eens kijken naar een scenario waarin de instelling voor automatisch groeien niet juist is ingesteld in de database. Dit is opnieuw een probleem:als automatische groei is ingeschakeld in de database, betekent dit dat de schijfuitbreiding automatisch plaatsvindt tijdens een bepaalde gebeurtenis, zelfs als de gegevens niet alle ruimte innemen.
Het is altijd een goede gewoonte om de juiste instelling voor automatisch groeien in te stellen voor het gegevensbestand. Soms kan de onjuiste instelling van het gegevensbestand fysieke fragmentatie veroorzaken, wat resulteert in ernstige prestatievermindering van het systeem. Met andere woorden, als u geen niet-toegewezen ruimte heeft, zullen de nieuwe gegevens proberen op lege, verspreide locaties te blijven. Dit geldt ook voor het logbestand. De niet-toegewezen ruimte in de database heeft indirect invloed op de auto-groei-instelling van het gegevensbestand en het logbestand en heeft direct invloed op de prestaties. De sleutel is het vinden van de juiste balans.
Afronden
- Tijdens het maken van de database is de gedefinieerde grootte (d.w.z. de initiële grootte) niets anders dan de werkelijke grootte van de database. Deze initiële grootte wordt vastgelegd in de paginakoptekst. Tijdens een databaseverkleiningsproces gebruikt het proces de minimale grootte eigenschap als referentie, alleen als de werkelijke gegevensgrootte kleiner is dan de minimumgrootte - de minimumgrootte wordt ook gevonden in de paginakoptekst en kan worden bekeken met de opdracht DBCC PAGE. Hetzelfde proces geldt ook voor DBCC SHRINKFILE, dat bestanden verkleint tot minder dan hun oorspronkelijke grootte.
- Het wordt niet aanbevolen om de database te verkleinen om schijfruimte vrij te maken, hoewel de beslissing afhankelijk is van het scenario - ongebruikelijke scenario's kunnen een onconventionele actie rechtvaardigen. Men moet echter niet vergeten dat het verkleinen van een database fragmentatie in de database introduceert. Het is altijd een goede gewoonte om de hoofdoorzaak van de niet-toegewezen ruimte te analyseren en ongebruikte ruimte van de objecten. In veel gevallen zou het uitbreiden van de schijf om de gegevensgroei aan te kunnen een haalbare/aanbevolen optie zijn.
- Auto-grow-configuratie:wanneer SQL Server een auto-grow-bewerking uitvoert, moet de transactie die de auto-grow-gebeurtenis heeft geactiveerd, wachten tot de auto-grow-gebeurtenis is voltooid. Alleen dan kan de transactie zelf worden voltooid.
- Het wordt altijd aanbevolen om de opties voor automatisch groeien in te stellen in aantallen in plaats van percentages.
- De inductie van ongebruikte ruimte in de tabel kan de volgende redenen hebben:
- Fragmentatie
Als gegevens gefragmenteerd zijn vanwege de aard en het type van de definitie, wordt er wat ongebruikte ruimte gegenereerd. Ook leidt een frequente wijziging van de gegevens (alle bewerkingen BIJWERKEN, INVOEREN OF VERWIJDEREN) tot meer paginasplitsingen, waardoor de kans groter is dat er ongebruikte ruimte in de tabel wordt gegenereerd. - Geen geclusterde index op tafel
Om fragmentatie in een Heap te verminderen, kan men denken aan het creëren van een geclusterde index op de tafel. Om indexfragmentatie te verminderen, voert u indexonderhoud uit door de waarde avg_fragmentation_in_percent te bepalen. - Grootte van de gegevens
In sommige gevallen levert het gebruik van de juiste gegevenstypen kleinere gegevensrijen op, waardoor er meer rijen op een pagina kunnen worden geplaatst. Het vermindert niet alleen de interne ongebruikte ruimte, maar heeft ook een impact op de prestaties door het aantal paginasplitsingen te verminderen.
- Fragmentatie
- De ongebruikte ruimte kan ook het gevolg zijn van het laten vallen van de kolom met variabele lengte. Gebruik DBCC CLANTABLE nadat u belangrijke wijzigingen hebt aangebracht in de kolommen met variabele lengte in een tabel of geïndexeerde weergave om de ongebruikte ruimte onmiddellijk terug te winnen. Als alternatief kunt u de indexen in de tabel of weergave opnieuw opbouwen; dit is echter een meer resource-intensieve operatie.
- De ongebruikte ruimte is relatief groter wanneer we uiteindelijk relatief grotere gegevens laden (>8 KB). In dergelijke gevallen eindigen we met grote hoeveelheden ongebruikte ruimte op de gegevenspagina's.
- Na een SharePoint-migratie kan een aanzienlijk deel van de ongebruikte ruimte in de databases worden geïntroduceerd. Het terugvorderen is een langzamer proces, het spookopruimingsproces verwijdert deze pagina's en het vrijmaken gebeurt na verloop van tijd.
- In sommige gevallen zijn de waarden van sp_spaceused mogelijk niet correct. Hoewel sp_spaceused zijn informatie haalt uit het systeemobject dat alle schattingen bevat, kan het soms onnauwkeurig zijn. Een van de redenen hiervoor is dat tijdens een databasemigratie, of in het geval van verouderde statistieken, of wanneer het systeem frequente DDL-wijzigingen ondergaat, of na het uitvoeren van grote bulkkopieerbewerkingen. Om systeemobjecten te synchroniseren, gebruikt u de DBCC updateusage(0)- of DBCC CHECKTABLE-instructies om ervoor te zorgen dat sp_spaceused up-to-date nauwkeurige gegevens retourneert. Onthoud echter dat DBCC-opdrachten veel resources vergen; een goed begrip hebben van de implicaties van het gebruik ervan. Wanneer we de opdracht DBCC updateusage uitvoeren, scant de SQL Server Database Engine de gegevenspagina's in de database en brengt de nodige correcties aan op de sys.allocation_units en sys.partitions catalogusweergaven met betrekking tot de opslagruimte die door elke tafel wordt gebruikt.
Referenties
- 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