You are on page 1of 4

#######################################################3333

--MANTENIMIENTO DE INDICES--

DECLARE @objectid int;


DECLARE @indexid int;
DECLARE @partitioncount bigint;
DECLARE @schemaname nvarchar(130);
DECLARE @objectname nvarchar(130);
DECLARE @indexname nvarchar(130);
DECLARE @partitionnum bigint;
DECLARE @partitions bigint;
DECLARE @frag float;
DECLARE @command nvarchar(4000);
DECLARE @Limite INT, @Contador INT;
Declare @BD_ID int;
select @BD_ID=DB_ID()
--Select @BD_ID

SELECT ROW_NUMBER() OVER(ORDER BY object_id) AS ID,


object_id AS objectid,
index_id AS indexid,
partition_number AS partitionnum,
avg_fragmentation_in_percent AS frag
INTO #work_to_do
-- select *
FROM sys.dm_db_index_physical_stats (@BD_ID, NULL, NULL , NULL, 'LIMITED')
WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;

--select * from #work_to_do

SELECT @Limite = COUNT(*) FROM #work_to_do

SET @Contador = 1
WHILE(@Contador <> @Limite+1)
BEGIN
select @objectid=objectid, @indexid=indexid,
@partitionnum=partitionnum, @frag=frag
FROM #work_to_do
WHERE ID=@Contador

SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)


FROM sys.objects AS o
JOIN sys.schemas as s ON s.schema_id = o.schema_id
WHERE o.object_id = @objectid;
SELECT @indexname = QUOTENAME(name)
FROM sys.indexes
WHERE object_id = @objectid AND index_id = @indexid;
SELECT @partitioncount = count (*)
FROM sys.partitions
WHERE object_id = @objectid AND index_id = @indexid;
-- 30 is an arbitrary decision point at which to switch between
reorganizing and rebuilding.
IF @frag < 30.0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' +
@schemaname + N'.' + @objectname + N' REORGANIZE WITH ( LOB_COMPACTION = ON )';
IF @frag >= 30.0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' +
@schemaname + N'.' + @objectname + N' REBUILD';
IF @partitioncount > 1
SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS
nvarchar(10));
Exec (@command);
PRINT (@command);
SET @Contador = @Contador + 1
END;

DROP TABLE #work_to_do;

#############################################################
-----------------------------------------------------------
--REVISAR FRAGMENTACION DE INDICES RESULTADO SIMPLE

SELECT
db.name as 'Database',
o.name as 'Table',
case when I.name is null then 'Heap' else I.name end as 'Indice',
left(avg_fragmentation_in_percent,4) as '% frag'

--FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL) AS a

FROM sys.dm_db_index_physical_stats (DB_ID('INVERCAP_468'), NULL, NULL, NULL, NULL)


AS a

--FROM sys.dm_db_index_physical_stats (DB_ID('NOMBRE BASE DE DATOS'),


OBJECT_ID('NOMBRE DE TABLA'), NULL, NULL, NULL) AS a

-- left para obtener nombre db --


LEFT JOIN Sys.Databases as DB
on A.Database_Id = DB.Database_Id

-- left para obtener nombre del idx --


LEFT JOIN sys.indexes AS I
ON
a.object_id = I.object_id AND
a.index_id = I.index_id

-- left para obtener nombre tabla --


LEFT JOIN sys.objects as o
on I.[object_id] = o.[object_id]
----------------
WHERE avg_fragmentation_in_percent > 20 -- % de fragmentacin en este caso > 20
and index_level = 0 --> analizando la rama principal de los ndices
and page_count > 1000 --> mas de 1000 hojas
order by

o.name

##########################################################################
ESTADO DETALLADO DE LOS INDICES

select CURRENT_TIMESTAMP as Fecha, DB_NAME(db_id()) as DatabaseName, @@servername


Servidor, b.name as IndexName, obj.name as ObjectName,
a.avg_fragmentation_in_percent as '%Frag', a.page_count as NumeroPaginas ,
a.fragment_count as PromPagFrag,a.index_type_desc as TipoIndice,
a.avg_fragment_size_in_pages, a.partition_number
FROM sys.dm_db_index_physical_stats(db_id(), NULL, NULL, NULL, 'limited') as a
INNER JOIN sys.indexes as b
ON a.object_id = b.object_id AND a.index_id = b.index_id
INNER JOIN sys.objects as Obj
ON a.object_id = Obj.object_id

---------------------------------------------------------
##########################################################################
REORGANIZA O RECONSTRUYE LOS INDICES SI LA FRAGMENTACION ES ARRIBA DEL 30%
SET NOCOUNT ON;
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @partitioncount bigint;
DECLARE @schemaname nvarchar(130);
DECLARE @objectname nvarchar(130);
DECLARE @indexname nvarchar(130);
DECLARE @partitionnum bigint;
DECLARE @partitions bigint;
DECLARE @frag float;
DECLARE @command nvarchar(4000);
-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats
function
-- and convert object and index IDs to names.
SELECT
object_id AS objectid,
index_id AS indexid,
partition_number AS partitionnum,
avg_fragmentation_in_percent AS frag
INTO #work_to_do
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0 AND page_count > 1000;

-- Declare the cursor for the list of partitions to be processed.


DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;

-- Open the cursor.


OPEN partitions;

-- Loop through the partitions.


WHILE (1=1)
BEGIN;
FETCH NEXT
FROM partitions
INTO @objectid, @indexid, @partitionnum, @frag;
IF @@FETCH_STATUS < 0 BREAK;
SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
FROM sys.objects AS o
JOIN sys.schemas as s ON s.schema_id = o.schema_id
WHERE o.object_id = @objectid;
SELECT @indexname = QUOTENAME(name)
FROM sys.indexes
WHERE object_id = @objectid AND index_id = @indexid;
SELECT @partitioncount = count (*)
FROM sys.partitions
WHERE object_id = @objectid AND index_id = @indexid;
-- 30 is an arbitrary decision point at which to switch between reorganizing and
rebuilding.
IF @frag < 30.0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname +
N'.' + @objectname + N' REORGANIZE';
IF @frag >= 30.0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname +
N'.' + @objectname + N' REBUILD';
IF @partitioncount > 1
SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS
nvarchar(10));
EXEC (@command);
PRINT N'Executed: ' + @command;
END;

-- Close and deallocate the cursor.


CLOSE partitions;
DEALLOCATE partitions;

-- Drop the temporary table.


DROP TABLE #work_to_do;
GO

You might also like