DBCC SHOWCONTIG (Transact-SQL)
Si applica a: SQL Server Istanza gestita di SQL di Azure
Visualizza informazioni sulla frammentazione dei dati e degli indici per la tabella o vista specificata.
Importante
Questa funzionalità verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Evitare di usare questa funzionalità in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata. Usare sys.dm_db_index_physical_stats in alternativa.
Si applica a: SQL Server 2008 (10.0.x) e versioni successive
Convenzioni di sintassi Transact-SQL
Sintassi
DBCC SHOWCONTIG
[ (
{ table_name | table_id | view_name | view_id }
[ , index_name | index_id ]
) ]
[ WITH
{
[ , [ ALL_INDEXES ] ]
[ , [ TABLERESULTS ] ]
[ , [ FAST ] ]
[ , [ ALL_LEVELS ] ]
[ NO_INFOMSGS ]
}
]
Nota
Per visualizzare la sintassi Transact-SQL per SQL Server 2014 e versioni precedenti, vedere Documentazione delle versioni precedenti.
Argomenti
table_name | table_id | view_name | view_id
Tabella o vista per verificare la presenza di informazioni sulla frammentazione. Se viene omesso, vengono controllate tutte le tabelle e le viste indicizzate nel database corrente. Per ottenere l'ID della tabella o vista, usare la funzione OBJECT_ID.
index_name | index_id
Indice da verificare per informazioni sulla frammentazione. Se viene omesso, l'istruzione elabora l'indice di base per la tabella o vista specificata. Per ottenere l'ID dell'indice, usare la vista del catalogo sys.indexes.
WITH
Specifica le opzioni per il tipo di informazioni restituite dall'istruzione DBCC.
FAST
Specifica se eseguire un'analisi rapida dell'indice con restituzione di informazioni di output minime. Un'analisi rapida non legge le pagine foglia o livello di dati dell'indice.
ALL_INDEXES
Visualizza i risultati per tutti gli indici delle tabelle e viste specificate, anche se viene indicato un indice specifico.
TABLERESULTS
Visualizza i risultati come set di righe, con informazioni aggiuntive.
ALL_LEVELS
Supportata per compatibilità con le versioni precedenti. Anche se ALL_LEVELS
viene specificato, viene elaborato solo il livello foglia di indice o il livello di dati della tabella.
NO_INFOMSGS
Evita la visualizzazione di tutti i messaggi informativi con livello di gravità compreso tra 0 e 10.
Set di risultati
Nella tabella seguente vengono descritte le informazioni del set di risultati.
Statistiche | Descrizione |
---|---|
Pagine sottoposte ad analisi | Numero di pagine della tabella o dell'indice. |
Extent sottoposti ad analisi | Numero di extent della tabella o dell'indice. |
Cambi di extent | Numero di passaggi dell'istruzione DBCC da un extent all'altro durante l'attraversamento delle pagine della tabella o dell'indice. |
Byte Pagine per extent | Numero di pagine per extent nella catena di pagine. |
Densità di analisi [conteggio ottimale: conteggio effettivo] | Percentuale. Rapporto tra Conteggio ottimale e Conteggio effettivo. Questo valore è 100 se tutti gli elementi sono contigui, è minore di 100 in presenza di frammentazioni. Conteggio ottimale rappresenta il numero ideale di cambi di extent se tutti gli elementi fossero contigui. Conteggio effettivo rappresenta il numero effettivo di cambi di extent. |
Frammentazione analisi logica | Percentuale di pagine non ordinate restituite dall'analisi delle pagine foglia di un indice. Questo numero non è rilevante per gli heaps. Una pagina out-of-order è una pagina per cui la pagina fisica successiva allocata all'indice non è la pagina puntata dal puntatore di page successivo nella pagina foglia corrente. |
Frammentazione analisi extent | Percentuale di extent non ordinati rilevati durante l'analisi delle pagine foglia di un indice. Questo numero non è rilevante per gli heaps. Un extent out-of-order è uno per cui l'extent che contiene la pagina corrente per un indice non è fisicamente l'extent successivo dopo l'extent che contiene la pagina precedente per un indice. Nota: Questo numero è senza significato quando l'indice si estende su più file. |
Byte disponibili per pagina | Numero medio di byte disponibili nelle pagine sottoposte ad analisi. Maggiore è il numero, minore sarà il livello di riempimento delle pagine. I numeri inferiori sono migliori se l'indice non avrà molti inserimenti casuali. Anche le dimensioni delle righe influiscono su questo valore, che risulta maggiore per righe di grandi dimensioni. |
Byte densità pagina (completa) | Densità media della pagina, in percentuale. Questo valore tiene conto delle dimensioni delle righe e pertanto rappresenta un'indicazione più precisa dell'effettivo livello di riempimento delle pagine. Sono preferibili valori elevati. |
Quando table_id e FAST vengono specificati, DBCC SHOWCONTIG
restituisce un set di risultati con solo le colonne seguenti:
- Pagine sottoposte ad analisi
- Cambi di extent
- Densità di analisi [conteggio ottimale:conteggio effettivo]
- Frammentazione analisi extent
- Frammentazione analisi logica
Quando TABLERESULTS
viene specificato, DBCC SHOWCONTIG
restituisce le colonne seguenti e anche le nove colonne descritte nella tabella precedente.
Statistiche | Descrizione |
---|---|
nome oggetto | Nome della tabella o vista elaborata. |
ObjectId | ID del nome di oggetto. |
IndexName | Nome dell'indice elaborato. NULL per un heap. |
IndexId | ID dell'indice. 0 per un heap. |
Level | Livello dell'indice. Il livello 0 corrisponde al livello foglia (o dati) dell'indice. Il livello è 0 per un heap. |
Pagine | Numero di pagine che compongono tale livello dell'indice o l'intero heap. |
prime righe | Numero di record di dati o dell'indice a tale livello dell'indice. Nel caso di un heap, corrisponde al numero di record di dati dell'intero heap. Per un heap, il numero di record restituiti da questa funzione potrebbe non corrispondere al numero di righe restituite eseguendo un SELECT COUNT(*) oggetto sull'heap. Questo perché una riga potrebbe contenere più record. Ad esempio, in alcune situazioni di aggiornamento, un'unica riga dell'heap potrebbe presentare un record di inoltro e un record inoltrato a seguito dell'operazione di aggiornamento. Inoltre, nell'archiviazione LOB_DATA la maggior parte delle righe LOB viene suddivisa in più record. |
MinimumRecordSize | Dimensioni minime dei record in tale livello dell'indice o nell'intero heap. |
MaximumRecordSize | Dimensioni massime dei record in tale livello dell'indice o nell'intero heap. |
AverageRecordSize | Dimensioni medie dei record in tale livello dell'indice o nell'intero heap. |
ForwardedRecords | Numero di record inoltrati in tale livello dell'indice o nell'intero heap. |
Extents | Numero di extent in tale livello dell'indice o nell'intero heap. |
ExtentSwitches | Numero di passaggi dell'istruzione DBCC da un extent all'altro durante l'attraversamento delle pagine della tabella o dell'indice. |
AverageFreeBytes | Numero medio di byte disponibili nelle pagine sottoposte ad analisi. Maggiore è il numero, minore sarà il livello di riempimento delle pagine. I numeri più bassi sono migliori se l'indice non includerà molti inserimenti casuali. Anche le dimensioni delle righe influiscono su questo valore, che risulta maggiore per righe di grandi dimensioni. |
AveragePageDensity | Densità media della pagina, in percentuale. Questo valore tiene conto delle dimensioni delle righe e pertanto rappresenta un'indicazione più precisa dell'effettivo livello di riempimento delle pagine. Sono preferibili valori elevati. |
ScanDensity | Percentuale. Rapporto tra BestCount e ActualCount. Questo valore è 100 se tutti gli elementi sono contigui, è minore di 100 in presenza di frammentazioni. |
BestCount | Il numero ideale di extent cambia se tutto è collegato in modo contiguo. |
ActualCount | Numero effettivo di modifiche di extent. |
LogicalFragmentation | Percentuale di pagine non ordinate restituite dall'analisi delle pagine foglia di un indice. Questo numero non è rilevante per gli heap. Una pagina non ordinata è una pagina per cui la pagina fisica successiva allocata all'indice non è la pagina a cui punta il puntatore di pagina successivo nella pagina foglia corrente. |
ExtentFragmentation | Percentuale di extent non ordinati rilevati durante l'analisi delle pagine foglia di un indice. Questo numero non è rilevante per gli heap. Un extent non ordinato è uno per il quale l'extent che contiene la pagina corrente per un indice non è fisicamente l'extent successivo dopo l'extent che contiene la pagina precedente per un indice. Nota: Questo numero è privo di significato quando l'indice si estende su più file. |
Quando WITH TABLERESULTS
e FAST
vengono specificati, il set di risultati è uguale a quando WITH TABLERESULTS
viene specificato, ad eccezione delle colonne seguenti con valori Null:
Righe | Extents |
---|---|
MinimumRecordSize | AverageFreeBytes |
MaximumRecordSize | AveragePageDensity |
AverageRecordSize | ExtentFragmentation |
ForwardedRecords |
Osservazioni
L'istruzione DBCC SHOWCONTIG
attraversa la catena di pagine a livello foglia dell'indice specificato quando viene specificato index_id . Se si specifica solo table_id oppure index_id è 0, viene eseguita l'analisi delle pagine di dati della tabella specificata. L'operazione richiede esclusivamente un blocco a livello di tabella preventivo condiviso (IS). In questo modo è possibile eseguire tutti gli aggiornamenti e gli inserimenti, con l'eccezione delle operazioni che richiedono un blocco a livello di tabella esclusivo (X). Ciò consente di ottenere una velocità di esecuzione accettabile senza riduzione della concorrenza per il numero di statistiche restituite. Tuttavia, se il comando viene usato solo per misurare la frammentazione, è consigliabile usare l'opzione WITH FAST
per ottenere prestazioni ottimali. Un'analisi veloce non legge le pagine foglia o a livello di dati dell'indice. L'opzione WITH FAST
non si applica a un heap.
Restrizioni
DBCC SHOWCONTIG
non visualizza i dati con tipi di dati ntext, text e image . La mancata visualizzazione è dovuta al fatto gli indici di testo che archiviano dati di tipo text e image non esistono più.
Inoltre, DBCC SHOWCONTIG
non supporta alcune nuove funzionalità. Ad esempio:
- Se la tabella o l'indice specificato è partizionata,
DBCC SHOWCONTIG
visualizza solo la prima partizione della tabella o dell'indice specificato. DBCC SHOWCONTIG
non visualizza informazioni sull'archiviazione di overflow delle righe e altri nuovi tipi di dati all'esterno delle righe, ad esempio nvarchar(max), varchar(max), varbinary(max)e xml.- Gli indici spaziali non sono supportati da
DBCC SHOWCONTIG
.
Tutte le nuove funzionalità sono completamente supportate dalla DMV sys.dm_db_index_physical_stats (Transact-SQL).
Frammentazione delle tabelle
DBCC SHOWCONTIG
determina se la tabella è fortemente frammentata. La frammentazione si verifica in seguito ai processi di modifica dei dati della tabella (istruzioni INSERT, UPDATE e DELETE). Poiché queste modifiche non vengono normalmente distribuite equamente tra le righe della tabella, la completezza di ogni pagina può variare nel tempo. Nel caso di query che eseguono l'analisi di un'intera tabella o di una parte di tabella, tale frammentazione della tabella potrebbe comportare letture di pagine aggiuntive, operazione che ostacola l'analisi parallela dei dati.
Per ridurre il livello di frammentazione di un indice molto frammentato, è possibile eseguire una delle operazioni seguenti:
Eliminare e ricreare un indice cluster.
Quando si ricrea un indice cluster, i dati vengono riorganizzati e si ottengono pagine di dati complete. Il livello di completezza può essere configurato usando l'opzione
FILLFACTOR
inCREATE INDEX
. Questo metodo presenta due svantaggi, ovvero l'indice rimane offline durante l'operazione di eliminazione o ricostruzione e l'operazione è atomica. Se la creazione dell'indice viene interrotta, l'indice non viene ricreato.Ridisporre in ordine logico le pagine del livello foglia dell'indice.
Usare
ALTER INDEX...REORGANIZE
per riordinare le pagine a livello foglia dell'indice in un ordine logico. L'operazione viene eseguita online e pertanto l'indice rimane disponibile durante l'esecuzione dell'istruzione. È inoltre possibile interrompere l'operazione senza perdere il lavoro completato. Lo svantaggio di questo metodo è che il metodo non funziona come un buon processo di riorganizzazione dei dati come un'operazione di eliminazione o ricreazione dell'indice cluster.Ricompilare l'indice.
Usare
ALTER INDEX
conREBUILD
per ricompilare l'indice. Per altre informazioni, vedere ALTER INDEX (Transact-SQL).
Il numero Media byte disponibili per pagina e Media densità pagina (completa) nel set di risultati indicano il livello di riempimento delle pagine dell'indice. Il numero medio di byte liberi per pagina deve essere basso e il numero medio di densità di pagina (pieno) deve essere elevato per un indice che non includerà molti inserimenti casuali. L'eliminazione e la ricreazione di un indice con l'opzione FILLFACTOR
specificata possono migliorare le statistiche. Inoltre, ALTER INDEX
con compattare REORGANIZE
un indice, tenendo conto del relativo FILLFACTOR
e migliorerà le statistiche.
Nota
Per un indice con numerosi inserimenti casuali e pagine molto piene si verificherà un maggior numero di divisioni di pagina e di conseguenza una maggiore frammentazione.
È possibile determinare il livello di frammentazione di un indice nei modi seguenti:
Tramite il confronto dei valori di Cambi di extent ed Extent sottoposti ad analisi.
Il valore Cambi di extent deve essere il più possibile prossimo al valore Extent sottoposti ad analisi. Questo rapporto viene calcolato dal valore Densità di analisi. Tale valore deve essere il più alto possibile e può essere migliorato riducendo la frammentazione dell'indice.
Nota
Questo metodo non funziona se l'indice è esteso a più file.
Tramite l'analisi dei valori Frammentazione analisi logica e Frammentazione analisi extent.
Il valore Frammentazione analisi logica e, anche se in misura minore, il valore Frammentazione analisi extent sono i migliori indicatori del livello di frammentazione di una tabella. Entrambi i valori dovrebbero essere il più possibile prossimi allo zero, anche se possono essere accettabili valori compresi tra 0% e 10%.
Nota
Il valore Frammentazione analisi extent sarà elevato se l'indice è esteso a più file. Per ridurre questo valore, è necessario ridurre la frammentazione dell'indice.
Autorizzazioni
L'utente deve essere il proprietario della tabella oppure un membro del ruolo predefinito del server sysadmin o dei ruoli predefiniti del database db_owner o db_ddladmin.
Esempi
R. Visualizzare le informazioni sulla frammentazione per una tabella
Nell'esempio seguente vengono visualizzate informazioni sulla frammentazione della tabella Employee
.
USE AdventureWorks2022;
GO
DBCC SHOWCONTIG ('HumanResources.Employee');
GO
B. Usare OBJECT_ID per ottenere l'ID tabella e sys.indexes per ottenere l'ID indice
Nell'esempio seguente vengono usate la funzione OBJECT_ID
e la vista del catalogo sys.indexes
per ottenere l'ID di tabella e l'ID di indice per l'indice AK_Product_Name
della tabella Production.Product
nel database AdventureWorks2022
.
USE AdventureWorks2022;
GO
DECLARE @id INT, @indid INT
SET @id = OBJECT_ID('Production.Product');
SELECT @indid = index_id
FROM sys.indexes
WHERE object_id = @id
AND name = 'AK_Product_Name';
DBCC SHOWCONTIG (@id, @indid);
GO
C. Visualizzare un set di risultati abbreviato per una tabella
Nell'esempio seguente viene restituito un set di risultati abbreviato per la tabella Product
nel database AdventureWorks2022
.
USE AdventureWorks2022;
GO
DBCC SHOWCONTIG ('Production.Product', 1) WITH FAST;
GO
D. Visualizzare il set di risultati completo per ogni indice in ogni tabella di un database
Nell'esempio seguente viene restituito un set completo di risultati relativi a ogni indice di tutte le tabelle del database AdventureWorks2022
.
USE AdventureWorks2022;
GO
DBCC SHOWCONTIG WITH TABLERESULTS, ALL_INDEXES;
GO
E. Usare DBCC SHOWCONTIG e DBCC INDEXDEFRAG per deframmentare gli indici in un database
Nell'esempio seguente viene illustrato un metodo semplice per deframmentare tutti gli indici di un database il cui livello di frammentazione è superiore alla soglia massima specificata.
/*Perform a 'USE <database name>' to select the database in which to run the script.*/
-- Declare variables
SET NOCOUNT ON;
DECLARE @tablename VARCHAR(255);
DECLARE @execstr VARCHAR(400);
DECLARE @objectid INT;
DECLARE @indexid INT;
DECLARE @frag DECIMAL;
DECLARE @maxfrag DECIMAL;
-- Decide on the maximum fragmentation to allow for.
SELECT @maxfrag = 30.0;
-- Declare a cursor.
DECLARE tables CURSOR FOR
SELECT TABLE_SCHEMA + '.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE';
-- Create the table.
CREATE TABLE #fraglist (
ObjectName CHAR(255),
ObjectId INT,
IndexName CHAR(255),
IndexId INT,
Lvl INT,
CountPages INT,
CountRows INT,
MinRecSize INT,
MaxRecSize INT,
AvgRecSize INT,
ForRecCount INT,
Extents INT,
ExtentSwitches INT,
AvgFreeBytes INT,
AvgPageDensity INT,
ScanDensity DECIMAL,
BestCount INT,
ActualCount INT,
LogicalFrag DECIMAL,
ExtentFrag DECIMAL);
-- Open the cursor.
OPEN tables;
-- Loop through all the tables in the database.
FETCH NEXT
FROM tables
INTO @tablename;
WHILE @@FETCH_STATUS = 0
BEGIN
-- Do the showcontig of all indexes of the table
INSERT INTO #fraglist
EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''')
WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS');
FETCH NEXT
FROM tables
INTO @tablename;
END;
-- Close and deallocate the cursor.
CLOSE tables;
DEALLOCATE tables;
-- Declare the cursor for the list of indexes to be defragged.
DECLARE indexes CURSOR FOR
SELECT ObjectName, ObjectId, IndexId, LogicalFrag
FROM #fraglist
WHERE LogicalFrag >= @maxfrag
AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0;
-- Open the cursor.
OPEN indexes;
-- Loop through the indexes.
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ',
' + RTRIM(@indexid) + ') - fragmentation currently '
+ RTRIM(CONVERT(varchar(15),@frag)) + '%';
SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ',
' + RTRIM(@indexid) + ')';
EXEC (@execstr);
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag;
END;
-- Close and deallocate the cursor.
CLOSE indexes;
DEALLOCATE indexes;
-- Delete the temporary table.
DROP TABLE #fraglist;
GO