DBCC SHOWCONTIG (Transact-SQL)
Se aplica a: SQL Server Azure SQL Managed Instance
Muestra información sobre la fragmentación de los datos y los índices de la tabla o vista especificada.
Importante
Esta característica se quitará en una versión futura de SQL Server. Evite utilizar esta característica en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente la utilizan. Use sys.dm_db_index_physical_stats en su lugar.
Se aplica a: SQL Server 2008 (10.0.x) y versiones posteriores
Convenciones de sintaxis de Transact-SQL
Sintaxis
DBCC SHOWCONTIG
[ (
{ table_name | table_id | view_name | view_id }
[ , index_name | index_id ]
) ]
[ WITH
{
[ , [ ALL_INDEXES ] ]
[ , [ TABLERESULTS ] ]
[ , [ FAST ] ]
[ , [ ALL_LEVELS ] ]
[ NO_INFOMSGS ]
}
]
Argumentos
table_name | table_id | view_name | view_id
La tabla o vista cuya información de fragmentación se va a comprobar. Si no se especifica, se comprueban todas las tablas y vistas indizadas de la base de datos actual. Para obtener el id. de la tabla o la vista, use la función OBJECT_ID.
index_name | index_id
El índice cuya información de fragmentación se va a comprobar. Si no se especifica, la instrucción procesa el índice base de la tabla o la vista especificada. Para obtener el id. del índice, use la vista de catálogo sys.indexes.
WITH
Especifica las opciones del tipo de información que devuelve la instrucción DBCC.
FAST
Especifica si se realiza un examen rápido del índice y se ofrece la mínima información de salida. Un examen rápido no lee las páginas de nivel de datos u hoja del índice.
ALL_INDEXES
Muestra el resultado de todos los índices para las tablas y vistas especificadas, aunque se haya especificado un índice determinado.
TABLERESULTS
Muestra el resultado como un conjunto de filas, con información adicional.
ALL_LEVELS
Se mantiene únicamente por compatibilidad con versiones anteriores. Aunque se especifique ALL_LEVELS
, solo se procesa el nivel hoja de índice o el nivel de datos de tabla.
NO_INFOMSGS
Suprime todos los mensajes informativos con niveles de gravedad entre 0 y 10.
Conjuntos de resultados
En la tabla siguiente se describe la información del conjunto de resultados.
Estadísticas | Descripción |
---|---|
Páginas examinadas | Número de páginas de la tabla o el índice. |
Extensiones examinadas | Número de extensiones de la tabla o el índice. |
Cambios de extensión | Número de veces que la instrucción DBCC se ha movido de una extensión a otra al examinar las páginas de la tabla o el índice. |
Avg. páginas por extensión | Número de páginas por extensión en la cadena de páginas. |
Densidad de examen [Mejor recuento: Recuento real] | Un porcentaje. Es la relación entre Mejor recuento y Recuento real. Este valor es 100 si todo es contiguo; si dicho valor es inferior a 100, existe fragmentación. Mejor recuento es el número ideal de cambios de extensión si todo está vinculado de forma contigua. Recuento real es el número real de cambios de extensión. |
Fragmentación de examen lógico | Porcentaje de páginas que no funcionan resultante del examen de las páginas hoja del índice. Este número no es relevante para los montones. Una página no ordenada es aquella en la que la siguiente página física asignada al índice no es la que señala el puntero de página siguiente en la página hoja actual. |
Fragmentación de examen de extensión | Porcentaje de extensiones que no funcionan resultante del examen de las páginas hoja del índice. Este número no es relevante para los montones. Una extensión que no funciona es aquella para la que la extensión que contiene la página actual de un índice no es físicamente la extensión siguiente a la que contiene la página anterior de un índice. Nota: Este número carece de significado si el índice abarca varios archivos. |
Avg. bytes libres por página | Valor promedio de los bytes libres de las páginas exploradas. Cuanto más alto es el número, menos llenas estarán las páginas. Los números más bajos funcionan mejor si el índice no contiene muchas inserciones aleatorias. Este número también está influido por el tamaño de la fila; un tamaño de fila grande puede provocar un número más alto. |
Avg. densidad de página (completa) | Promedio de densidad de página en porcentaje. Este valor tiene en cuenta el tamaño de la fila. Por consiguiente, dicho valor es una medida más precisa del grado de llenado de las páginas. Cuanto mayor sea el porcentaje, mejor. |
Cuando se especifica table_id y FAST, DBCC SHOWCONTIG
devuelve un conjunto de resultados con solo las columnas siguientes:
- Páginas examinadas
- Cambios de extensión
- Densidad de examen [Mejor recuento:Recuento real]
- Fragmentación de examen de extensión
- Fragmentación de examen lógico
Si se especifica TABLERESULTS
, DBCC SHOWCONTIG
devuelve las siguientes columnas además de las nueve columnas descritas en la tabla anterior.
Estadísticas | Descripción |
---|---|
Nombre de objeto | Nombre de la tabla o la vista procesada. |
ObjectId | Id. del nombre del objeto. |
IndexName | Nombre del índice procesado. NULL para un montón. |
IndexId | Id. del índice. 0 para un montón. |
Level | Nivel del índice. El nivel 0 es el nivel hoja o datos del índice. Para un montón, Level es 0. |
Páginas | Número de páginas que componen el nivel del índice o de todo el montón. |
Filas | Número de registros de datos o índices en este nivel del índice. Para un montón, este valor es el número de registros de datos en todo el montón. En el caso de un montón, es posible que el número de registros devueltos por esta función no coincida con el número de filas devueltas al ejecutar SELECT COUNT(*) en el montón. Esto es debido a que una fila puede contener varios registros. Por ejemplo, en algunas situaciones de una actualización, una única fila del montón puede tener un registro de reenvío y un registro reenviado como resultado de la actualización. Asimismo, la mayoría de las filas LOB de gran tamaño se dividen en varios registros en almacenamiento de LOB_DATA. |
MinimumRecordSize | Tamaño mínimo del registro en el nivel de índice o en todo el montón. |
MaximumRecordSize | Tamaño máximo del registro en el nivel del índice o en todo el montón. |
AverageRecordSize | Promedio de tamaño del registro en el nivel de índice o en todo el montón. |
ForwardedRecords | Número de registros reenviados en el nivel de índice o en todo el montón. |
Extents | Número de extensiones en el nivel de índice o en todo el montón. |
ExtentSwitches | Número de veces que la instrucción DBCC se ha movido de una extensión a otra al examinar las páginas de la tabla o el índice. |
AverageFreeBytes | Valor promedio de los bytes libres de las páginas exploradas. Cuanto más alto es el número, menos llenas estarán las páginas. Los números más bajos funcionan mejor si el índice no contiene muchas inserciones aleatorias. Este número también está influido por el tamaño de la fila; un tamaño de fila grande puede provocar un número más alto. |
AveragePageDensity | Promedio de densidad de página en porcentaje. Este valor tiene en cuenta el tamaño de la fila. Por consiguiente, dicho valor es una medida más precisa del grado de llenado de las páginas. Cuanto mayor sea el porcentaje, mejor. |
ScanDensity | Un porcentaje. Es la relación entre BestCount y ActualCount. Este valor es 100 si todo es contiguo; si dicho valor es inferior a 100, existe fragmentación. |
BestCount | El número idóneo de cambios de extensión si todo está vinculado de forma contigua. |
ActualCount | El número real de cambios de extensión. |
LogicalFragmentation | Porcentaje de páginas que no funcionan resultante del examen de las páginas hoja del índice. Este número no es relevante para los montones. Una página no ordenada es aquella en la que la siguiente página física asignada al índice no es la que señala el puntero de página siguiente en la página hoja actual. |
ExtentFragmentation | Porcentaje de extensiones que no funcionan resultante del examen de las páginas hoja del índice. Este número no es relevante para los montones. Una extensión que no funciona es aquella para la que la extensión que contiene la página actual de un índice no es físicamente la extensión siguiente a la que contiene la página anterior de un índice. Nota: Este número carece de significado si el índice abarca varios archivos. |
Cuando se especifican WITH TABLERESULTS
y FAST
, el conjunto de resultados es el mismo que cuando se especifica WITH TABLERESULTS
, con la diferencia de que las siguientes columnas tendrán valores null:
Filas | Extents |
---|---|
MinimumRecordSize | AverageFreeBytes |
MaximumRecordSize | AveragePageDensity |
AverageRecordSize | ExtentFragmentation |
ForwardedRecords |
Observaciones
Cuando se especifica index_id, la instrucción DBCC SHOWCONTIG
recorre la cadena de páginas en el nivel hoja del índice especificado. Si solo se especifica id_de_tabla o si id_de_índice es 0, se examinan las páginas de datos de la tabla especificada. Esta operación solo requiere un bloqueo de tabla con intención compartida (IS). De este modo, se pueden realizar todas las actualizaciones e inserciones excepto las que requieren un bloqueo de tabla exclusivo (X). Esto permite un equilibrio entre la velocidad de ejecución y la no reducción de la simultaneidad con respecto al número de estadísticas devueltas. Pero si el comando se va a usar solo para medir la fragmentación, se recomienda la opción WITH FAST
para que el rendimiento sea óptimo. Un examen rápido no lee las páginas de nivel de datos u hoja del índice. La opción WITH FAST
no se aplica a un montón.
Restricciones
DBCC SHOWCONTIG
no muestra los datos con los tipos de datos ntext, text e image. Esto se debe a que ya no existen índices de texto que almacenan datos de texto e imagen.
Además, DBCC SHOWCONTIG
no admite algunas de las nuevas características. Por ejemplo:
- Si la tabla o el índice especificados tienen particiones,
DBCC SHOWCONTIG
solo muestra la primera partición de la tabla o el índice especificados. DBCC SHOWCONTIG
no muestra la información de almacenamiento de desbordamiento de fila y otros tipos de datos no consecutivos nuevos como nvarchar(max), varchar(max), varbinary(max) y xml.DBCC SHOWCONTIG
no admite los índices espaciales.
Todas las características nuevas son totalmente compatibles con la vista de administración dinámica sys.dm_db_index_physical_stats (Transact-SQL).
Fragmentación de tablas
DBCC SHOWCONTIG
determina si la tabla está muy fragmentada. La fragmentación de las tablas es consecuencia de los procesos de modificación de los datos (instrucciones INSERT, UPDATE y DELETE) efectuados en las tablas. Como dichas modificaciones no suelen estar distribuidas de forma equilibrada entre todas las filas de la tabla, el llenado de cada página puede variar con el paso del tiempo. En las consultas que examinan la totalidad o parte de una tabla, esta fragmentación de tabla puede ocasionar lecturas de páginas adicionales. Esto impide el examen paralelo de los datos.
Cuando un índice está muy fragmentado, existen dos opciones para reducir la fragmentación:
Quite y vuelva a crear un índice clúster.
La reconstrucción de un índice clúster reorganiza los datos y hace que las páginas de datos se llenen. El grado de llenado puede configurarse con la opción
FILLFACTOR
deCREATE INDEX
. El inconveniente de este método es que el índice está sin conexión durante el proceso de eliminación y nueva creación, y que la operación es atómica. Si se interrumpe la creación del índice, no vuelve a crearse.Reordene las páginas de nivel hoja del índice en un orden lógico.
Use
ALTER INDEX...REORGANIZE
para reordenar las páginas de nivel hoja del índice en un orden lógico. Dado que esta operación se realiza en línea, el índice está disponible mientras se ejecuta la instrucción. También es posible interrumpir la operación sin perder todo el trabajo. El inconveniente de este método es que no es una forma tan buena de reorganizar los datos como la operación de quitar y volver a crear el índice clúster.Vuelva a generar el índice.
Use
ALTER INDEX
conREBUILD
para volver a crear el índice. Para más información, vea ALTER INDEX (Transact-SQL).
Las estadísticas Avg. bytes libres por página y Promedio de densidad de página (completa) del conjunto de resultados indican el llenado de las páginas de índice. El número promedio de bytes libres por página debe ser bajo y el número promedio de densidad de página (completa) debe ser alto para un índice que no tenga muchas inserciones aleatorias. Quitar y volver a crear un índice con la opción FILLFACTOR
especificada puede mejorar estas estadísticas. Además, ALTER INDEX
con REORGANIZE
compactará un índice, teniendo en cuenta FILLFACTOR
, lo que mejorará las estadísticas.
Nota
En un índice que contenga muchas inserciones aleatorias y páginas muy llenas se produce un aumento de las divisiones de páginas. Esto causa más fragmentación.
El nivel de fragmentación de un índice puede determinarse de las siguientes formas:
Mediante la comparación de los valores de Cambios de extensión y Extensiones examinadas.
El valor de Cambios de extensión debe ser lo más parecido posible al de Extensiones examinadas. Esta relación se calcula como el valor de Densidad del examen. Dicho valor debe ser lo más alto posible y se puede aumentar mediante la reducción de la fragmentación del índice.
Nota
Este método no funciona si el índice abarca varios archivos.
Mediante la comprensión de los valores de Fragmentación de examen lógico y Fragmentación de examen de extensión.
Los valores de Fragmentación de examen lógico y, en menor medida, los de Fragmentación de examen de extensión, ofrecen la mejor indicación del nivel de fragmentación de una tabla. Ambos valores deberían tender a cero tanto como fuera posible, aunque puede ser aceptable un valor entre el 0 y el 10 por ciento.
Nota
El valor de Fragmentación de examen de extensión es alto si el índice abarca varios archivos. Para reducir estos valores, debe reducir la fragmentación del índice.
Permisos
El usuario debe ser propietario de la tabla o ser un miembro del rol fijo de servidor sysadmin o de los roles fijos de base de datos db_owner o db_ddladmin.
Ejemplos
A. Presentación de la información de fragmentación de una tabla
En el siguiente ejemplo se muestra la información de fragmentación para la tabla Employee
.
USE AdventureWorks2022;
GO
DBCC SHOWCONTIG ('HumanResources.Employee');
GO
B. Uso de OBJECT_ID para obtener el id. de la tabla y sys.indexes para obtener el id. del índice
En el siguiente ejemplo se usa OBJECT_ID
y la vista de catálogo sys.indexes
para obtener el id. de tabla y el id. de índice para el índice AK_Product_Name
de la tabla Production.Product
de la base de datos 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. Visualización de un conjunto de resultados resumido de una tabla
En el siguiente ejemplo se devuelve un conjunto de resultados resumido para la tabla Product
de la base de datos AdventureWorks2022
.
USE AdventureWorks2022;
GO
DBCC SHOWCONTIG ('Production.Product', 1) WITH FAST;
GO
D. Visualización del conjunto de resultados completo para todos los índices de todas las tablas de la base de datos
En el siguiente ejemplo se devuelve un conjunto de resultados de tabla completo para todos los índices de todas las tablas de la base de datos AdventureWorks2022
.
USE AdventureWorks2022;
GO
DBCC SHOWCONTIG WITH TABLERESULTS, ALL_INDEXES;
GO
E. Uso de DBCC SHOWCONTIG y DBCC INDEXDEFRAG para desfragmentar los índices de una base de datos
En el siguiente ejemplo se muestra una forma sencilla de desfragmentar todos los índices de una base de datos que está fragmentada por encima de un umbral declarado.
/*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