Mostrando las entradas con la etiqueta REBUILD. Mostrar todas las entradas
Mostrando las entradas con la etiqueta REBUILD. Mostrar todas las entradas

martes, 29 de marzo de 2016

REORGANIZE OR REBUILD INDEX



-- =========================================================================================
-- AUTOR:           MANUEL OMAR OLGUÍN HERNÁNDEZ
-- FECHA            15-JUL-2013
-- DESCRIPCIÓN      REORGANIZA O RECONSTRUYE LOS ÍNDICES DE LA BASES DE DATOS QUE CONTENGAN FRAGMENTACIÓN SOBRE SUS TABLAS ENTRE
-- 5  - 30 % REORGANIZE
-- 31 - 100% REBUILD
--
-- NOTA:            EN LA BASE SELECCIONADA SEGÚN EL CONTEXTO
-- =========================================================================================

USE DATABASENAME;
GO






 SELECT I.NAME AS INDICE , T.NAME AS TABLENAME, S.NAME AS SCHEMANAME, AVG_FRAGMENTATION_IN_PERCENT
             ,IND.INDEX_TYPE_DESC
             ,IND.DATABASE_ID
             ,IND.INDEX_ID
             ,DB.NAME AS DATABASE_NAME
             ,ID = ROW_NUMBER () OVER (ORDER BY I.NAME, IND.INDEX_ID)
 INTO #INDICES
 FROM SYS.DM_DB_INDEX_PHYSICAL_STATS (NULL,null,NULL,NULL,NULL)AS IND
 INNER JOIN SYS.INDEXES AS I ON IND.OBJECT_ID = I.OBJECT_ID
 INNER JOIN SYS.TABLES AS T ON IND.OBJECT_ID = T.OBJECT_ID
 INNER JOIN SYS.SCHEMAS AS S ON T.SCHEMA_ID = S.SCHEMA_ID
 INNER JOIN SYS.DATABASES AS DB ON IND.DATABASE_ID = DB.DATABASE_ID
 WHERE IND.INDEX_ID > 0 AND I.NAME IS NOT NULL
 AND IND.AVG_FRAGMENTATION_IN_PERCENT BETWEEN 5 AND 100



 -- SELECT * FROM #INDICES order by ID

 DECLARE @ID               INT
 DECLARE @INDICE           NVARCHAR(500)
 DECLARE @INDEX_ID         INT
 DECLARE @SCHEMANAME       VARCHAR(200);
 DECLARE @TABLENAME        VARCHAR(200);
 DECLARE @STRSQL           NVARCHAR(500);
 DECLARE @DESCRIPTION      NVARCHAR (500);
 DECLARE @INDEX_TYPE       NVARCHAR (50);
 DECLARE @INSTRUCCION      NVARCHAR(150);
 DECLARE @FRAGMENTATION    DECIMAL (8,2)
 SET @ID =0


 WHILE (@ID IS NOT NULL)
  BEGIN

  /*
   SET @SCHEMANAME  = (SELECT TOP 1 SCHEMANAME                                  FROM #INDICES WHERE INDICE > @INDICE ORDER BY INDICE )
   SET @TABLENAME   = (SELECT TOP 1 TABLENAME                                   FROM #INDICES WHERE INDICE > @INDICE ORDER BY INDICE )
   SET @INDICE             = (SELECT TOP 1 INDICE                                             FROM #INDICES WHERE INDICE > @INDICE ORDER BY INDICE )
   SET @DESCRIPTION = (SELECT TOP 1 AVG_FRAGMENTATION_IN_PERCENT   FROM #INDICES WHERE INDICE > @INDICE ORDER BY INDICE )
   */

   IF @ID IS NOT NULL
             BEGIN

                SELECT           TOP 1
                                        @SCHEMANAME         = SCHEMANAME,
                                        @TABLENAME          = TABLENAME,
                                        @INDICE                    = INDICE,
                                        @FRAGMENTATION      = AVG_FRAGMENTATION_IN_PERCENT,
                                        @INDEX_TYPE         = INDEX_TYPE_DESC,                           
                                        @INDEX_ID           = INDEX_ID
                FROM                    #INDICES
                WHERE ID > @ID
                ORDER BY ID

                SET @ID   = (SELECT TOP 1 ID                                    FROM #INDICES WHERE ID > @ID ORDER BY ID )


                IF @FRAGMENTATION <= 30 SET @INSTRUCCION = 'REORGANIZE';
                          
                      --IF @FRAGMENTATION > 30  SET @INSTRUCCION = 'REBUILD';
                IF @FRAGMENTATION > 30  SET @INSTRUCCION = 'REBUILD PARTITION = ALL WITH (FILLFACTOR = 85)';



                SET @STRSQL             = ('ALTER INDEX ' + @INDICE + ' ON ' + @SCHEMANAME + '.' + @TABLENAME + ' ' + @INSTRUCCION)
                SET @DESCRIPTION = 'ID:' + CONVERT(VARCHAR, @ID) +  '  INDEX:' + CONVERT(VARCHAR,@INDEX_ID) + ' ' + @STRSQL + '   - ' + @INDEX_TYPE  + '   AVG FRAGMENTATION:' + CONVERT(VARCHAR,@FRAGMENTATION);
                RAISERROR (@DESCRIPTION,0,1) WITH NOWAIT

                EXECUTE SP_EXECUTESQL @STRSQL
             END
   
 END




 

   SELECT I.NAME AS INDICE , T.NAME AS TABLENAME, S.NAME AS SCHEMANAME, AVG_FRAGMENTATION_IN_PERCENT
             ,IND.INDEX_TYPE_DESC
             ,IND.DATABASE_ID
             ,IND.INDEX_ID
             ,DB.NAME AS DATABASE_NAME
             ,ID = ROW_NUMBER () OVER (ORDER BY I.NAME, IND.INDEX_ID)
 INTO #INDICES_REBUILD
 FROM SYS.DM_DB_INDEX_PHYSICAL_STATS (NULL,null,NULL,NULL,NULL)AS IND
 INNER JOIN SYS.INDEXES AS I ON IND.OBJECT_ID = I.OBJECT_ID
 INNER JOIN SYS.TABLES AS T ON IND.OBJECT_ID = T.OBJECT_ID
 INNER JOIN SYS.SCHEMAS AS S ON T.SCHEMA_ID = S.SCHEMA_ID
 INNER JOIN SYS.DATABASES AS DB ON IND.DATABASE_ID = DB.DATABASE_ID
 WHERE IND.INDEX_ID > 0 AND I.NAME IS NOT NULL
 AND IND.AVG_FRAGMENTATION_IN_PERCENT BETWEEN 0 AND 100





 SELECT             A.Indice, A.SchemaName, A.TableName
                    ,OLD_FRAGMENTATION = CONVERT(DECIMAL(5,2),(A.AVG_FRAGMENTATION_IN_PERCENT))
                    ,NEW_FRAGMENTATION = CONVERT(DECIMAL(5,2),(B.AVG_FRAGMENTATION_IN_PERCENT))
                    ,Fragmentation = CONVERT(VARCHAR(10), CONVERT(DECIMAL(5,2), (A.AVG_FRAGMENTATION_IN_PERCENT)  - (B.AVG_FRAGMENTATION_IN_PERCENT))) + '%'
                    ,A.INDEX_ID 
                    ,A.INDEX_TYPE_DESC AS INDEX_TYPE
                    ,A.DATABASE_NAME
                   
 FROM        #INDICES                   AS A
 LEFT JOIN   #INDICES_REBUILD    AS B ON A.TABLENAME = B.TABLENAME AND A.SCHEMANAME = B.SCHEMANAME AND A.DATABASE_ID = B.DATABASE_ID AND A.INDEX_ID = B.INDEX_ID AND A.INDICE = B.INDICE
 ORDER BY A.SCHEMANAME, A.TABLENAME, A.INDICE, A.INDEX_ID




 DROP TABLE #INDICES;
 DROP TABLE #INDICES_REBUILD




































  /* To rebuild all indexes in a table changing the fillfactor (cuando se hace el rebuild conviene ajustar el fill factor de nuevo, por si ya está lleno)*/
--ALTER INDEX ALL ON Avispa.Brokers
--REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON,STATISTICS_NORECOMPUTE = ON);