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

SQL Server:analizza gli interni di sp_spaceused

Questo articolo è uno sforzo per analizzare l'output di sp_spaceused procedura memorizzata.

Introduzione

La comprensione degli interni di utilizzo del database e le tendenze di crescita svolgono un ruolo fondamentale nella definizione del corretto dimensionamento del database. sp_spaceused è probabilmente la stored procedure di sistema più utilizzata da un amministratore per trovare lo spazio su disco utilizzato da un database. Questo aiuta a dare una rapida occhiata all'utilizzo del database. statistiche. sp_spaceused viene utilizzato per visualizzare il numero di righe, la dimensione dei dati, la dimensione dell'indice, la quantità di spazio utilizzato, lo spazio non utilizzato da ciascun oggetto e la dimensione non allocata del database. Sebbene guardando i valori forniti da sp_spaceused, non si dovrebbe pensare di ridurre il database o il file di dati o il file di registro. Molte volte, non siamo consapevoli di ciò che stiamo facendo. Molte volte, non sappiamo quali sarebbero gli effetti collaterali dell'esecuzione di tali operazioni intrinseche delle risorse. L'output di sp_spaceused ci dice molto sulle prestazioni correnti del database. Il non allocato colonna e non utilizzato la colonna indica lo spazio libero rimasto nel database e nei livelli della tabella.

Questo articolo considera:

  1. Una sbirciatina in sp_spaceused
  2. Impatto dell'impostazione di crescita automatica sulle colonne, non allocate e non utilizzate
  3. Trovare i dettagli sull'utilizzo dello spazio a livello di database e di istanza
  4. Misurare gli eventi di crescita automatica
  5. Trovare le dimensioni dei file mdf e ldf
  6. Fattori che determinano le prestazioni del database
  7. E altro ancora...

Interni di sp_spaceused

Acquisisci i dettagli sull'utilizzo dello spazio di tutte le tabelle

Nel seguente T-SQL, la stored procedure non documentata sp_MSforeachtable viene utilizzata per attraversare tutte le tabelle nell'ambito del contesto del database corrente per ottenere le metriche di utilizzo dello spazio di tutte le tabelle nel contesto.

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

Acquisisci i dettagli sull'utilizzo dello spazio di tutti i database

La stored procedure non documentata sp_MSforeachDB viene utilizzata per attraversare l'intero database nell'ambito dell'istanza SQL corrente per ottenere le informazioni sull'utilizzo dello spazio di tutti i database.

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

Qui, nome_database è il nome del database; in questo caso, PythonSample . dimensione_database è l'Uallocato+Riservato+Dati+Indice+Non utilizzato =MDF +LDF (=848 MB in questo caso). Il non allocato lo spazio qui è 51,94 MB.

Questo è, in realtà, il limite del disco che è stato contrassegnato per il database. La sp_spaceused restituisce una colonna non allocata definita a livello di database e non è riservata ad alcuna tabella e può essere presa dal primo oggetto che rivendica più spazio per crescere.

Il non allocato lo spazio è lo spazio libero all'interno del file di dati in modo che non debba crescere automaticamente ogni volta che si esegue una query; in genere, il motore di archiviazione di SQL Server gestisce la crescita automatica utilizzando un meccanismo noto come algoritmo di riempimento proporzionale. La gestione delle estensioni viene eseguita in modo efficace in base al numero di scritture che avvengono sui file. E allo stesso tempo, quando lo spazio utilizzato raggiunge una soglia, viene attivato un evento per un'ulteriore crescita automatica. L'impostazione del valore corretto dello spazio non allocato dipende dalle esigenze e dalle situazioni e dalla natura di utilizzo del database. Lo spazio non allocato è lo spazio che non è ancora in uso ed è "in palio". In sostanza, queste estensioni sono contrassegnate con il bit 1 nella pagina GAM. Comprendendo il concetto di autocrescita dall'alto, qualsiasi tipo di crescita può generare ulteriori estensioni non allocate.

Utilizzando la seguente query SQL, possiamo vedere il numero di volte in cui è stato generato l'evento di crescita automatica, insieme alla quantità di tempo che il database ha tenuto in attesa per il processo.

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

Diamo un'occhiata al significato di ciascuno dei termini:

Prenotato :lo spazio riservato per l'uso da parte degli oggetti del database =(Dati +Indice + Non utilizzato ) =476704 + 1280 + 1312 =479296 KB. Questo indica quanto sono pieni gli oggetti; idealmente, per le tabelle transazionali è previsto il 10% dello spazio inutilizzato.

Dati :la dimensione effettiva dei dati. Questa è la somma di tutti i file di dati del database.

Indice :la quantità di spazio utilizzata dall'indice.

Nota:in alcuni casi, ho visto che la dimensione della dimensione dell'indice è maggiore della dimensione dei dati effettivi. Per quanto riguarda gli indici, ciò che è necessario per il sistema dipende sempre dalle prestazioni del database. Molte volte, le operazioni di lettura sono più importanti delle operazioni di scrittura. E in alcuni altri casi, le scritture sono più importanti delle letture. Nei casi in cui l'azienda ha deciso che le letture sono molto più importanti delle scritture, il sistema potrebbe richiedere tonnellate di indici per soddisfare i requisiti di prestazioni dell'azienda e degli utenti.

Non utilizzato :Una parte dello spazio riservato, che non è ancora utilizzato

Non utilizzate sono le pagine su estensioni allocate ma non ancora utilizzate da alcun oggetto. Non appena viene allocata un'estensione (come estensione uniforme o condivisa), otteniamo otto pagine riservate su quell'estensione. Alcune pagine vengono utilizzate e altre non vengono utilizzate.

Il non utilizzato e non allocato le colonne nell'output possono creare confusione. Per chiarire, il non utilizzato l'output della colonna non mostra la quantità di spazio libero rimasto nell'intero database. È, invece, la quantità totale di spazio riservato alle tabelle ma non riempito di dati. In molti casi, lo spazio inutilizzato può essere recuperato creando un indice cluster o gestendo gli indici esistenti.

L'output di sp_spaceused può essere ulteriormente semplificato per trovare la dimensione del file .mdf e dei file .log. La somma dello spazio riservato e dello spazio non allocato è più o meno uguale alla dimensione del file di dati o MDF. Inoltre, sottraendo la dimensione del file MDF dalla dimensione del database si ottiene la dimensione del file di registro.

Quindi ecco due formule:

Dimensione del file MDF =spazio riservato + non allocato

Dimensione del file di registro =Dimensione_database – Dimensione file MDF

SELECT 476704+ 1280+ 1312 'Reserved KB', (479296/1024.00)+51.94 'MDFSizeMB', 848.00 - ((479296/1024.00)+51.94) 'LogSizeMB'

I punti sopra citati ci dicono come ciascuna delle colonne nell'output di sp_spaceused viene interpretata, calcolata e analizzata.

Impatto dell'impostazione della crescita automatica

Le dimensioni iniziali e la configurazione di autocrescita hanno un effetto significativo sullo spazio inutilizzato. Impostare i valori giusti per questi è una sfida. Ho visto molti casi in cui la crescita automatica era destinata a crescere in termini percentuali. Supponiamo che la crescita automatica sia impostata al 25% per una dimensione del file di dati di 100 GB. Occorrono solo 4 eventi di crescita automatica per riempire l'unità disco.

L'altro caso è la ricostruzione degli indici. Questa operazione ha un impatto diretto sullo spazio inutilizzato della tabella, poiché i dati vengono rimescolati tra le estensioni uniformi e miste. In alcuni casi, mentre si rimescolano le pagine, l'operazione può causare spazio non allocato a causa dell'impostazione di crescita automatica del file di dati.

Consideriamo uno scenario in cui l'impostazione di crescita automatica non è impostata correttamente nel database. Anche questo è un problema:se la crescita automatica è abilitata nel database, significa che l'espansione dell'unità avviene automaticamente durante alcuni eventi anche se i dati non utilizzano tutto lo spazio.

È sempre buona norma impostare l'impostazione di crescita automatica appropriata per il file di dati. A volte, l'impostazione errata del file di dati può iniettare la frammentazione fisica, con conseguente grave degrado delle prestazioni del sistema. In altre parole, se non si dispone di spazio non allocato, i nuovi dati cercheranno di risiedere in posizioni vuote che potrebbero essere sparse. Questo vale anche per il file di registro. Lo spazio non allocato nel database influenza indirettamente l'impostazione di crescita automatica del file di dati e del file di registro e influenza direttamente le prestazioni. La loro chiave è trovare il giusto equilibrio.

Conclusione

  1. Nel processo di creazione del database, la dimensione definita (cioè la dimensione iniziale) non è altro che la dimensione effettiva del database. Questa dimensione iniziale viene registrata nell'intestazione della pagina. Durante un processo di compattazione del database, il processo utilizza la dimensione minima proprietà come riferimento, solo se la dimensione dei dati effettiva è inferiore alla dimensione minima:la dimensione minima si trova anche nell'intestazione della pagina e può essere visualizzata usando il comando DBCC PAGE. Inoltre, lo stesso processo vale per DBCC SHRINKFILE, che riduce i file a dimensioni inferiori alle loro dimensioni iniziali.
  2. Non è una pratica consigliata ridurre il database per liberare spazio su disco, anche se la decisione dipende dallo scenario:scenari insoliti possono giustificare un'azione non convenzionale. Tuttavia, bisogna ricordare che la riduzione di un database introduce la frammentazione nel database. È sempre buona norma analizzare la causa principale dello spazio non allocato e spazio inutilizzato degli oggetti. In molti casi, l'espansione del disco per gestire la crescita dei dati sarebbe un'opzione praticabile/consigliata.
  3. Configurazione dell'aumento automatico:quando SQL Server esegue un'operazione di aumento automatico, la transazione che ha attivato l'evento di aumento automatico dovrà attendere il completamento dell'evento di aumento automatico. Solo allora la transazione stessa può essere completata.
  4. Si consiglia sempre di impostare le opzioni di crescita automatica in numeri anziché in percentuali.
  5. L'induzione di spazio inutilizzato nella tabella potrebbe essere dovuta ai seguenti motivi:
    • Frammentazione
      Quando i dati sono frammentati a causa della natura e del tipo di definizione, viene generato uno spazio inutilizzato. Inoltre, una frequente modifica dei dati (tutte le operazioni UPDATE, INSERT O DELETE) porta a un numero maggiore di divisioni di pagina, che è più probabile che generi spazio inutilizzato nella tabella.
    • Nessun indice cluster sul tavolo
      Per ridurre la frammentazione in un heap, si può pensare di creare un indice cluster sul tavolo. Per ridurre la frammentazione dell'indice, esegui la manutenzione dell'indice determinando il valore avg_fragmentation_in_percent.
    • Dimensione dei dati
      In alcuni casi, l'utilizzo di tipi di dati appropriati produce righe di dati più piccole che a loro volta consentono di posizionare più righe in una pagina. Non solo riduce lo spazio interno inutilizzato, ma ha anche un impatto sulle prestazioni riducendo il numero di divisioni di pagina.
  6. Lo spazio inutilizzato potrebbe anche essere il risultato dell'eliminazione della colonna a lunghezza variabile. Utilizzare DBCC CLEANTABLE dopo aver apportato modifiche significative alle colonne a lunghezza variabile in una tabella o in una vista indicizzata per recuperare immediatamente lo spazio inutilizzato. In alternativa, puoi ricostruire gli indici sulla tabella o sulla vista; tuttavia, questa è un'operazione che richiede più risorse.
  7. Lo spazio inutilizzato è relativamente più grande quando finiamo per caricare dati relativamente più grandi (>8 KB). In questi casi, ci ritroviamo con grandi quantità di spazio inutilizzato sulle pagine di dati.
  8. Dopo una migrazione di SharePoint, è possibile visualizzare una quantità significativa dello spazio inutilizzato introdotto nei database. Il recupero è un processo più lento, il processo di pulizia fantasma rimuove queste pagine e la liberazione avviene in un periodo di tempo.
  9. In alcuni casi, i valori di sp_spaceused potrebbero non essere corretti. Sebbene sp_spaceused ottenga le sue informazioni dall'oggetto di sistema che contiene tutte le stime, a volte può essere impreciso. Uno dei motivi è che durante una migrazione del database, o in caso di statistiche obsolete, o quando il sistema è sottoposto a frequenti modifiche DDL o dopo aver eseguito enormi operazioni di copia di massa. Per sincronizzare gli oggetti di sistema, utilizzare le istruzioni DBCC updateusage(0) o DBCC CHECKTABLE per assicurarsi che sp_spaceused restituisca dati accurati e aggiornati. Tuttavia, ricorda che i comandi DBCC richiedono molte risorse; avere una buona comprensione delle implicazioni del suo utilizzo. Quando eseguiamo il comando DBCC updateusage, Motore di database di SQL Server esegue la scansione delle pagine di dati nel database e apporta le correzioni necessarie a sys.allocation_units e sys.partitions viste del catalogo relative allo spazio di archiviazione utilizzato da ciascuna tabella.

Riferimenti

  • 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