En las reglas de SSW para una mejor base de datos de SQL Server hay un ejemplo de un plan de mantenimiento de base de datos completo: SSW. En el ejemplo, ejecutan un Reorganize Index y luego un Rebuild Index y luego Update Statistics. ¿Hay algún punto para esto? Pensé que reorganizar Index era una versión rápida pero menos efectiva de Rebuild Index? y que una reconstrucción de índice también actualizaría las estadísticas automáticamente (al menos en el índice agrupado).Reorganizar índice vs Reconstruir índice en el plan de mantenimiento de servidor SQL
Respuesta
Haciendo un REORGANIZE
y luego un REBUILD
en los mismos índices no tiene sentido, ya que cualquier cambio de la REORGANIZE
se perderían haciendo lo REBUILD
.
Peor que eso es que en el diagrama de plan de mantenimiento de SSW, realiza primero un SHRINK
, que fragmenta los índices como un efecto secundario de la forma en que libera espacio. Luego, el REBUILD
asigna más espacio a los archivos de la base de datos como espacio de trabajo durante la operación REBUILD
.
REORGANIZE
es una operación en línea que desfragmenta páginas de hoja en una página de índice agrupado o no agrupado por página utilizando poco espacio de trabajo adicional.REBUILD
es una operación en línea en ediciones Enterprise, sin conexión en otras ediciones, y utiliza tanto espacio de trabajo adicional de nuevo como el tamaño del índice. Crea una nueva copia del índice y luego descarta la anterior, eliminando así la fragmentación. Las estadísticas se vuelven a calcular de manera predeterminada como parte de esta operación, pero se pueden deshabilitar.
Consulte Reorganizing and Rebuilding Indexes para obtener más información.
No utilice SHRINK
, excepto con la opción TRUNCATEONLY
e incluso entonces si el archivo volverá a crecer entonces debería pensar seriamente en cuanto a si es necesario:
La reorganización y la reconstrucción son cosas diferentes.
Reorganizar: es una desfragmentación para los índices. Toma los índices existentes y defragmenta las páginas existentes. Sin embargo, si las páginas no están contiguas, se mantienen como antes. Solo el contenido de las páginas está cambiando.
Reconstrucción: en realidad, se quita el índice y se reconstruye desde cero. Significa que obtendrá un índice completamente nuevo, con páginas desfragmentadas y contiguas.
Además, con la reconstrucción puede cambiar las particiones o los grupos de archivos, pero con reorganizar puede desfragmentar no solo todo el índice, sino también una sola partición del índice.
Las estadísticas de actualización son automáticas en los índices agrupados, pero no en los no agrupados.
Correcto, pero ¿hay algún uso para tener una reorganización y una reconstrucción en el mismo sub plan de mantenimiento? – codeulike
En realidad, de acuerdo con Books Online http://msdn.microsoft.com/en-us/library/ms189858.aspx Reorg reorganiza las páginas para hacerlas físicamente contiguas. Aquí está la cita exacta: "La reorganización de un índice desfragmenta el nivel hoja de índices agrupados y no agrupados en tablas y vistas reordenando físicamente las páginas de nivel hoja para que coincida con el orden lógico (de izquierda a derecha) de los nodos hoja. para mejorar el rendimiento del análisis de índice. El índice se reorganiza dentro de las páginas existentes asignadas, no se asignan páginas nuevas ". –
@ MichaelK.Campbell: Su cita fue tomada un poco fuera de contexto. Mientras ReOrg volverá a ordenar las páginas, SÓLO las reordena en el nivel más bajo que los nodos de niveles intermedios señalan a ellas. Después de reordenar, no se garantiza que todas las páginas de todo el índice sean contiguas. Aquí hay una mejor explicación: http://dba.stackexchange.com/a/36817/6816 – MikeTeeVee
dijo exactamente lo que Biri dijo. Aquí es cómo iba a indexar una base de datos completa:
Cuando se realiza una reorganización de un índice, si el índice se extiende a través de dos o más archivos físicos los datos sólo serán defragged dentro del archivo de datos. Las páginas no se mueven de un archivo de datos a otro.
Cuando el índice está en un solo archivo, la reorganización y reindex tendrán el mismo resultado final.
Algunas veces la reorganización será más rápida, y algunas veces el reindexamiento será más rápido dependiendo de qué tan fragmentado sea el índice. Mientras menos fragmentado sea el índice, una reorganización será más rápida, cuanto más fragmentada, más lenta será la reorganización, pero más rápido será un reindex.
Aún mejor es:
EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? REINDEX'
o
EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? REORGANIZE'
Yo uso este SP
CREATE PROCEDURE dbo.[IndexRebuild]
AS
DECLARE @TableName NVARCHAR(500);
DECLARE @SQLIndex NVARCHAR(MAX);
DECLARE @RowCount INT;
DECLARE @Counter INT;
DECLARE @IndexAnalysis TABLE
(
AnalysisID INT IDENTITY(1, 1)
NOT NULL
PRIMARY KEY ,
TableName NVARCHAR(500) ,
SQLText NVARCHAR(MAX) ,
IndexDepth INT ,
AvgFragmentationInPercent FLOAT ,
FragmentCount BIGINT ,
AvgFragmentSizeInPages FLOAT ,
PageCount BIGINT
)
BEGIN
INSERT INTO @IndexAnalysis
SELECT [objects].name ,
'ALTER INDEX [' + [indexes].name + '] ON ['
+ [schemas].name + '].[' + [objects].name + '] '
+ (CASE WHEN ( [dm_db_index_physical_stats].avg_fragmentation_in_percent >= 20
AND [dm_db_index_physical_stats].avg_fragmentation_in_percent < 40
) THEN 'REORGANIZE'
WHEN [dm_db_index_physical_stats].avg_fragmentation_in_percent > = 40
THEN 'REBUILD'
END) AS zSQL ,
[dm_db_index_physical_stats].index_depth ,
[dm_db_index_physical_stats].avg_fragmentation_in_percent ,
[dm_db_index_physical_stats].fragment_count ,
[dm_db_index_physical_stats].avg_fragment_size_in_pages ,
[dm_db_index_physical_stats].page_count
FROM [sys].[dm_db_index_physical_stats](DB_ID(), NULL, NULL,
NULL, 'LIMITED') AS [dm_db_index_physical_stats]
INNER JOIN [sys].[objects] AS [objects] ON ( [dm_db_index_physical_stats].[object_id] = [objects].[object_id])
INNER JOIN [sys].[schemas] AS [schemas] ON ([objects].[schema_id] = [schemas].[schema_id])
INNER JOIN [sys].[indexes] AS [indexes] ON ( [dm_db_index_physical_stats].[object_id] = [indexes].[object_id]
AND [dm_db_index_physical_stats].index_id = [indexes].index_id
)
WHERE index_type_desc <> 'HEAP'
AND [dm_db_index_physical_stats].avg_fragmentation_in_percent > 20
END
SELECT @RowCount = COUNT(AnalysisID)
FROM @IndexAnalysis
SET @Counter = 1
WHILE @Counter <= @RowCount
BEGIN
SELECT @SQLIndex = SQLText
FROM @IndexAnalysis
WHERE AnalysisID = @Counter
EXECUTE sp_executesql @SQLIndex
SET @Counter = @Counter + 1
END
GO
y crear un puesto de trabajo que ejecute este SP todas las semanas.
Mis dos centavos ... Este método sigue la especificación se indica en la red de tecnología: http://technet.microsoft.com/en-us/library/ms189858(v=sql.105).aspx
USE [MyDbName]
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE PROCEDURE [maintenance].[IndexFragmentationCleanup]
AS
DECLARE @reIndexRequest VARCHAR(1000)
DECLARE reIndexList CURSOR
FOR
SELECT INDEX_PROCESS
FROM (
SELECT CASE
WHEN avg_fragmentation_in_percent BETWEEN 5
AND 30
THEN 'ALTER INDEX [' + i.NAME + '] ON [' + t.NAME + '] REORGANIZE;'
WHEN avg_fragmentation_in_percent > 30
THEN 'ALTER INDEX [' + i.NAME + '] ON [' + t.NAME + '] REBUILD with(ONLINE=ON);'
END AS INDEX_PROCESS
,avg_fragmentation_in_percent
,t.NAME
FROM sys.dm_db_index_physical_stats(NULL, NULL, NULL, NULL, NULL) AS a
INNER JOIN sys.indexes AS i ON a.object_id = i.object_id
AND a.index_id = i.index_id
INNER JOIN sys.tables t ON t.object_id = i.object_id
WHERE i.NAME IS NOT NULL
) PROCESS
WHERE PROCESS.INDEX_PROCESS IS NOT NULL
ORDER BY avg_fragmentation_in_percent DESC
OPEN reIndexList
FETCH NEXT
FROM reIndexList
INTO @reIndexRequest
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
PRINT @reIndexRequest;
EXEC (@reIndexRequest);
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT @ErrorMessage = 'UNABLE TO CLEAN UP INDEX WITH: ' + @reIndexRequest + ': MESSAGE GIVEN: ' + ERROR_MESSAGE()
,@ErrorSeverity = 9
,@ErrorState = ERROR_STATE();
END CATCH;
FETCH NEXT
FROM reIndexList
INTO @reIndexRequest
END
CLOSE reIndexList;
DEALLOCATE reIndexList;
RETURN 0
GO
He investigado en la web y encontré algunos de los buenos artículos. En el y escribí la función y el script a continuación que reorganiza, recrea o reconstruye todos los índices en una base de datos.
Primero debe leer this article para comprender por qué no solo recreamos todos los índices.
En segundo lugar, necesitamos una función para crear el script de creación para el índice. Entonces this article puede ayudar. También estoy compartiendo la función de trabajo a continuación.
Último paso haciendo un ciclo while para encontrar y organizar todos los índices en la base de datos. This video es un buen ejemplo para hacer esto.
Función:
create function GetIndexCreateScript(
@index_name nvarchar(100)
)
returns nvarchar(max)
as
begin
declare @Return varchar(max)
SELECT @Return = ' CREATE ' +
CASE WHEN I.is_unique = 1 THEN ' UNIQUE ' ELSE '' END +
I.type_desc COLLATE DATABASE_DEFAULT +' INDEX ' +
I.name + ' ON ' +
Schema_name(T.Schema_id)+'.'+T.name + ' (' +
KeyColumns + ') ' +
ISNULL(' INCLUDE ('+IncludedColumns+') ','') +
ISNULL(' WHERE '+I.Filter_definition,'') + ' WITH (' +
CASE WHEN I.is_padded = 1 THEN ' PAD_INDEX = ON ' ELSE ' PAD_INDEX = OFF ' END + ',' +
'FILLFACTOR = '+CONVERT(CHAR(5),CASE WHEN I.Fill_factor = 0 THEN 100 ELSE I.Fill_factor END) + ',' +
-- default value
'SORT_IN_TEMPDB = OFF ' + ',' +
CASE WHEN I.ignore_dup_key = 1 THEN ' IGNORE_DUP_KEY = ON ' ELSE ' IGNORE_DUP_KEY = OFF ' END + ',' +
CASE WHEN ST.no_recompute = 0 THEN ' STATISTICS_NORECOMPUTE = OFF ' ELSE ' STATISTICS_NORECOMPUTE = ON ' END + ',' +
-- default value
' DROP_EXISTING = ON ' + ',' +
-- default value
' ONLINE = OFF ' + ',' +
CASE WHEN I.allow_row_locks = 1 THEN ' ALLOW_ROW_LOCKS = ON ' ELSE ' ALLOW_ROW_LOCKS = OFF ' END + ',' +
CASE WHEN I.allow_page_locks = 1 THEN ' ALLOW_PAGE_LOCKS = ON ' ELSE ' ALLOW_PAGE_LOCKS = OFF ' END + ') ON [' +
DS.name + ' ] '
FROM sys.indexes I
JOIN sys.tables T ON T.Object_id = I.Object_id
JOIN sys.sysindexes SI ON I.Object_id = SI.id AND I.index_id = SI.indid
JOIN (SELECT * FROM (
SELECT IC2.object_id , IC2.index_id ,
STUFF((SELECT ' , ' + C.name + CASE WHEN MAX(CONVERT(INT,IC1.is_descending_key)) = 1 THEN ' DESC ' ELSE ' ASC ' END
FROM sys.index_columns IC1
JOIN Sys.columns C
ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
AND IC1.is_included_column = 0
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
GROUP BY IC1.object_id,C.name,index_id
ORDER BY MAX(IC1.key_ordinal)
FOR XML PATH('')), 1, 2, '') KeyColumns
FROM sys.index_columns IC2
--WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
GROUP BY IC2.object_id ,IC2.index_id) tmp3)tmp4
ON I.object_id = tmp4.object_id AND I.Index_id = tmp4.index_id
JOIN sys.stats ST ON ST.object_id = I.object_id AND ST.stats_id = I.index_id
JOIN sys.data_spaces DS ON I.data_space_id=DS.data_space_id
JOIN sys.filegroups FG ON I.data_space_id=FG.data_space_id
LEFT JOIN (SELECT * FROM (
SELECT IC2.object_id , IC2.index_id ,
STUFF((SELECT ' , ' + C.name
FROM sys.index_columns IC1
JOIN Sys.columns C
ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
AND IC1.is_included_column = 1
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
GROUP BY IC1.object_id,C.name,index_id
FOR XML PATH('')), 1, 2, '') IncludedColumns
FROM sys.index_columns IC2
--WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
GROUP BY IC2.object_id ,IC2.index_id) tmp1
WHERE IncludedColumns IS NOT NULL) tmp2
ON tmp2.object_id = I.object_id AND tmp2.index_id = I.index_id
WHERE I.is_primary_key = 0 AND I.is_unique_constraint = 0
AND I.[name] = @index_name
return @Return
end
SQL para rato:
declare @RebuildIndex Table(
IndexId int identity(1,1),
IndexName varchar(100),
TableSchema varchar(50),
TableName varchar(100),
Fragmentation decimal(18,2)
)
insert into @RebuildIndex (IndexName,TableSchema,TableName,Fragmentation)
SELECT
B.[name] as 'IndexName',
Schema_Name(O.[schema_id]) as 'TableSchema',
OBJECT_NAME(A.[object_id]) as 'TableName',
A.[avg_fragmentation_in_percent] Fragmentation
FROM sys.dm_db_index_physical_stats(db_id(),NULL,NULL,NULL,'LIMITED') A
INNER JOIN sys.indexes B ON A.[object_id] = B.[object_id] and A.index_id = B.index_id
INNER JOIN sys.objects O ON O.[object_id] = B.[object_id]
where B.[name] is not null and B.is_primary_key = 0 AND B.is_unique_constraint = 0 and A.[avg_fragmentation_in_percent] >= 5
--select * from @RebuildIndex
declare @begin int = 1
declare @max int
select @max = Max(IndexId) from @RebuildIndex
declare @IndexName varchar(100), @TableSchema varchar(50), @TableName varchar(100) , @Fragmentation decimal(18,2)
while @begin <= @max
begin
Select @IndexName = IndexName from @RebuildIndex where IndexId = @begin
select @TableSchema = TableSchema from @RebuildIndex where IndexId = @begin
select @TableName = TableName from @RebuildIndex where IndexId = @begin
select @Fragmentation = Fragmentation from @RebuildIndex where IndexId = @begin
declare @sql nvarchar(max)
if @Fragmentation < 31
begin
set @sql = 'ALTER INDEX ['[email protected]+'] ON ['[email protected]+'].['[email protected]+'] REORGANIZE WITH (LOB_COMPACTION = ON)'
print 'Reorganized Index ' + @IndexName + ' for ' + @TableName + ' Fragmentation was ' + convert(nvarchar(18),@Fragmentation)
end
else
begin
set @sql = (select dbo.GetIndexCreateScript(@IndexName))
if(@sql is not null)
begin
print 'Recreated Index ' + @IndexName + ' for ' + @TableName + ' Fragmentation was ' + convert(nvarchar(18),@Fragmentation)
end
else
begin
set @sql = 'ALTER INDEX ['[email protected]+'] ON ['[email protected]+'].['[email protected]+'] REBUILD PARTITION = ALL WITH (ONLINE = ON)'
print 'Rebuilded Index ' + @IndexName + ' for ' + @TableName + ' Fragmentation was ' + convert(nvarchar(18),@Fragmentation)
end
end
execute(@sql)
set @begin = @begin+1
end
Antes de considerar el mantenimiento de índices, es importante responder a dos cuestiones principales:
- ¿Cuál es el grado de ¿fragmentación?
- ¿Cuál es la acción adecuada? Reorganizar o reconstruir?
Como se describe en este artículo http://solutioncenter.apexsql.com/why-when-and-how-to-rebuild-and-reorganize-sql-server-indexes/, y para ayudar a determinar si se debe realizar la reconstrucción de índices o reorganización de índices, por favor entender lo siguiente:
Índice de reorganización es un proceso donde va el SQL Server a través del índice existente, y lo limpia. La reconstrucción de índices es un proceso de alta resistencia en el que se elimina el índice y luego se recrea desde cero con una estructura completamente nueva, libre de todos los fragmentos acumulados y las páginas de espacio vacío.
Mientras que la reorganización de índice es una operación de limpieza pura que deja el estado del sistema como está sin bloquear las tablas y vistas afectadas, el proceso de reconstrucción bloquea la tabla afectada durante todo el período de reconstrucción, lo que puede provocar tiempos de inactividad prolongados. no podría ser aceptable en algunos entornos. Teniendo esto en cuenta, está claro que la reconstrucción del índice es un proceso con una solución "más sólida", pero tiene un precio: posibles bloqueos largos en las tablas indexadas afectadas.
Por otro lado, el índice de reorganización es un proceso ‘ligera’ que va a resolver la fragmentación de una manera menos eficaz - ya que el índice limpiado siempre será la segunda a la nueva totalmente hecha a partir de cero. Pero reorganizar el índice es mucho mejor desde el punto de vista de la eficiencia, ya que no bloquea la tabla indexada afectada durante el curso de la operación.
El artículo mencionado anteriormente también explica cómo reorganizar y reconstruir índices utilizando SSMS, T-SQL (para reorganizar/reconstruir índices en una tabla) y una herramienta de terceros llamada ApexSQL Backup.
- 1. Reconstrucción de índice en el servidor sql
- 2. ¿Cómo reconstruir el índice de texto completo?
- 3. Índice filtrados del servidor SQL
- 4. SQL Server: Ejecutar programáticamente plan de mantenimiento
- 5. Reorganizar y reconstruir índices automáticamente
- 6. Diferencia entre trabajos y plan de mantenimiento en el servidor sql
- 7. Missing Índice detalles SQL
- 8. Cómo crear un plan de mantenimiento en SQL Server?
- 9. No se puede modificar el plan de mantenimiento en SSMS
- 10. MongoDB - índice único vs índice compuesto
- 11. Índice Columna clave Índice VS incluida Columna
- 12. asp.net mvc RedirectToAction ("Índice") vs Índice()
- 13. No se encontró ningún servidor en el índice; no puedo reconstruir
- 14. Script para reconstruir y reindexar el índice fragmentado?
- 15. Obtener fecha de creación de índice del servidor SQL
- 16. Partición del servidor SQL - Error de índice único
- 17. índice agrupado de SQL Server - Orden del Índice Pregunta
- 18. ¿Cuál es su plan de copia de seguridad/mantenimiento de SQL Server?
- 19. SQL Server: índice normal versus índice de texto completo
- 20. SQL Server Coste del índice
- 21. Postgres GIST vs índice Btree
- 22. ¿La clave única del servidor Sql también es un índice?
- 23. ¿Índice no agrupado en una columna de índice agrupado mejora el rendimiento?
- 24. ¿Cuándo se actualiza el índice de texto completo en el servidor sql?
- 25. desempaquetado de Tuple: variable ficticia vs índice
- 26. clave primaria sql e índice
- 27. índice z vs translate3D en Chrome
- 28. ¿El índice no agrupado de SQL Server 2008 contiene los campos de índice agrupados?
- 29. ¿Debo definir el índice (A) y el índice (B), o el índice (A, B) o ambos?
- 30. Cómo seleccionar un índice SQL
¡Es increíble cuántas "autoridades" en línea son totalmente incorrectas y engañosas, es decir, sugiriendo que debe hacer una reducción en una base de datos! –