SQL Server en la práctica

Diagnosticar registros reenviados en heaps SQL Server

Mide movimientos de filas en heaps y relaciónalos con lecturas y latencia antes de decidir entre reconstruir o cambiar el diseño de la tabla.

Un heap puede ser adecuado para datos temporales y comportarse de otra forma tras meses de actualizaciones. Si una fila variable crece, su página original puede quedarse sin espacio. SQL Server puede moverla y dejar información de reenvío en la ubicación anterior.

Reproducir el crecimiento en una tabla desechable

Un heap carece de índice clustered, pero puede tener índices nonclustered. El ejemplo declara explícitamente la clave primaria nonclustered para no cambiar esa estructura accidentalmente. Ejecútalo en una base de práctica con el nombre disponible.

CREATE TABLE dbo.HeapForwardDemo
(
    RowId int NOT NULL PRIMARY KEY NONCLUSTERED,
    Payload varchar(1000) NOT NULL
);
;WITH N AS
(
    SELECT TOP (10000)
        CONVERT(int, ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) AS n
    FROM sys.all_objects AS a CROSS JOIN sys.all_objects AS b
)
INSERT dbo.HeapForwardDemo (RowId, Payload)
SELECT n, REPLICATE('a', 100) FROM N;

UPDATE dbo.HeapForwardDemo
SET Payload = REPLICATE('b', 900)
WHERE RowId % 2 = 0;

El contenido inicial es corto y después la mitad de las filas crece mucho. La cantidad de reenvíos depende de distribución y espacio libre. Mídela en lugar de esperar un porcentaje fijo.

SELECT
    index_id, partition_number, alloc_unit_type_desc,
    page_count, record_count,
    forwarded_record_count,
    avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats
(
    DB_ID(), OBJECT_ID(N'dbo.HeapForwardDemo'), 0, NULL, 'DETAILED'
)
WHERE alloc_unit_type_desc = 'IN_ROW_DATA';

La inspección apunta a un heap en modo DETAILED. Las estadísticas físicas pueden generar bastante E/S y requieren permisos adecuados. No sustituyas el filtro de objeto por NULL en producción para obtener un informe aparentemente completo.

forwarded_record_count evidencia movimiento. page_count y ocupación media describen el resto de la distribución. Una métrica NULL en un modo menos detallado no equivale a cero. Guarda modo, partición y unidad de asignación junto al resultado.

Relacionar almacenamiento y trabajo

Los índices nonclustered de un heap utilizan localizadores que pueden llevar primero al sitio original y después a la fila movida. La navegación adicional puede costar, pero su cantidad no mide por sí sola la latencia. Importan acceso, caché y frecuencia de lectura.

Identifica consultas afectadas y captura lecturas lógicas, CPU, duración y planes reales con parámetros representativos. Compara cargas similares. Si las filas también crecieron nueve veces, más páginas y menor densidad explican parte del cambio independientemente del reenvío.

Un índice que cubre una consulta puede evitar acceder al heap para ciertos datos, pero añade almacenamiento y mantenimiento. Otras consultas siguen leyendo filas base. Elige índices por patrones útiles, no para ocultar un problema sin explicar.

Distingue también reenvío y fragmentación lógica de un B-tree. Una rutina basada únicamente en avg_fragmentation_in_percent puede pasar por alto el problema relevante. Los heaps requieren interpretación específica y evidencia de carga.

Elegir según el ciclo de vida

Reconstruir el heap puede eliminar reenvíos actuales sin impedir otros por futuras expansiones. Los comandos siguientes afectan solo al objeto de práctica. Repite la inspección después de reconstruir y antes de eliminarlo.

ALTER TABLE dbo.HeapForwardDemo REBUILD;
-- Run the inspection query again before removing the test table.
DROP TABLE dbo.HeapForwardDemo;

En producción, planifica duración, capacidad del log, espacio, bloqueos y efectos en índices nonclustered. Reconstruir solo uno de estos índices no reorganiza las filas base. Un umbral arbitrario de reenvíos no justifica automáticamente un trabajo grande.

Un clustered bien elegido puede encajar en una tabla persistente con lecturas por clave y actualizaciones frecuentes. Cambia localizadores e introduce costes de divisiones de páginas y ancho de clave. Escoge una clave estable según la carga.

Para staging que se carga, procesa y descarta, conservar el heap puede ser correcto. La limpieza sigue el ciclo del lote. Para filas persistentes que crecen, revisa si esa expansión posterior es necesaria o resultado del flujo de escritura.

Relaciona la medición posterior con consultas y recurrencia. Si los reenvíos vuelven rápido y la latencia apenas mejora, reconstruir repetidamente trata un síntoma. Conserva también tiempo desde la carga y volumen de updates. Así la estrategia responde al uso real y no a una cifra aislada de un informe de mantenimiento.

Referencias técnicas: Microsoft Learn: Heaps · Microsoft Learn: Index physical statistics · Microsoft Learn: ALTER TABLE.

Pregunta sobre este artículo

¿Tiene alguna pregunta sobre este tema?

Cuéntenos qué está evaluando o dónde tiene dificultades. Le responderemos con una recomendación práctica.

Inquiries are not enabled in this preview.

Hacer una pregunta sobre este artículo