Sunday, May 18, 2014

To take script out of Rebuild and Statistics of Indexes on Databases

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);
DECLARE @onlineflag varchar(3);
DECLARE @MsgBody  NVARCHAR(MAX) ;
Declare @sqlcommand  varchar(max);
DECLARE @objectid_var varchar(30);
Declare @allow_page_locks int;


Create table #work_to_do
(objectid int,
indexid int,
partitionnum int,
indexdepth tinyint ,
index_level tinyint,
frag float,
onlineflag varchar(3)
)

Create table #work_to_do1
(
sqlcommand  varchar(max)
)

DECLARE table_cursor
CURSOR FOR select id from sys.sysobjects
where type='u'

-- Open the cursor.
OPEN table_cursor;

FETCH NEXT
FROM table_cursor
INTO  @objectid

WHILE (1 = 1)
BEGIN;

IF @@FETCH_STATUS < 0 BREAK;

SET @objectid_var=convert(varchar(30),@objectid)

SET @sqlCOMMAND='INSERT INTO #work_to_do
SELECT
object_id AS objectid,
index_id AS indexid,
partition_number AS partitionnum,
index_depth AS indexdepth,
index_level AS indexlevel,
avg_fragmentation_in_percent AS frag,''ON''
FROM sys.dm_db_index_physical_stats (DB_ID(),'+ @objectid_var + ', NULL, NULL , NULL)
WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0';


--print @sqlCOMMAND

exec (@sqlCOMMAND)

FETCH NEXT
FROM table_cursor
INTO @objectid;

END;

-- Close and deallocate the cursor.
CLOSE table_cursor;
DEALLOCATE table_cursor;

--select * from #work_to_do



Update #work_to_do
set ONLINEflag='OFF'
from  sys.indexes A,INFORMATION_SCHEMA.COLUMNS c,#work_to_do B
where a.type_desc = 'CLUSTERED'
      and   (DATA_TYPE IN ('text', 'ntext', 'image') OR
            CHARACTER_MAXIMUM_LENGTH = -1)
            and TABLE_NAME=OBJECT_NAME(A.object_id)
            AND A.object_id=B.objectid
            AND A.index_id=B.indexid

Update #work_to_do
set ONLINEflag='OFF'
from #work_to_do A,sys.indexes i
                  JOIN sys.index_columns ic
                  ON i.object_id = ic.object_id
                  JOIN INFORMATION_SCHEMA.COLUMNS c
                        ON ic.column_id = c.ORDINAL_POSITION
                  WHERE c.TABLE_NAME = OBJECT_NAME(i.object_id) AND
                              ic.is_included_column = 1 AND
                              (c.DATA_TYPE IN ('text', 'ntext', 'image') OR c.CHARACTER_MAXIMUM_LENGTH = -1)
            AND A.objectid=I.object_id
            AND A.indexid=I.index_id


SET @MsgBody =
    N'<H1>Fragmented Indexes</H1>' +
    N'<table border="1">' +
    N'<tr><th>DBNAME</th><th>Table_Name</th><th>Index_Name</th>' +
    N'<th>Fragmentation</th><th>Index Operation</th><th>Online_Flag</th></tr>' +
    CAST ( ( SELECT td = db_name(),       '',
                        td = object_name(objectid),     '',
                    td = name, '',
                    td = convert(varchar(8),frag), '',
                    td = Case When frag>=30.0 Then 'REBUILD'
                                                When frag  >= 10 and frag < 30.0 Then  'REORGANIZE' END,'',
                    td = onlineflag, ''               
         FROM    #work_to_do a,sys.sysindexes b
where a.objectid=b.id
and a.indexid=b.indid
order by frag,onlineflag
              FOR XML PATH('tr'), TYPE
    ) AS NVARCHAR(MAX) ) +
    N'</table>' ;
   
    /*EXEC msdb.dbo.sp_send_dbmail
    @recipients='xxxxxxxx@xxxxx.com;',
    @subject = 'Fragmented Index Report',
    @body = @MsgBody ,
    @body_format = 'HTML' ;*/



DECLARE Index_cursor
CURSOR FOR select object_name(objectid),name,frag,onlineflag,allow_page_locks
FROM    #work_to_do a,sys.indexes b
where a.objectid=b.object_id
and a.indexid=b.index_id

-- Open the cursor.
OPEN Index_cursor;

FETCH NEXT
FROM Index_cursor
INTO   @objectname,@indexname,@frag,@onlineflag,@allow_page_locks

WHILE (1 = 1)
BEGIN;

IF @@FETCH_STATUS < 0 BREAK;

if @frag>=30
seT @sqlcommand='ALTER INDEX ['+@indexname+'] ON [dbo].['+@objectname+'] REBUILD WITH (ONLINE='+@onlineflag +')'
ELSE
If @allow_page_locks=1
seT @sqlcommand='ALTER INDEX ['+@indexname+'] ON [dbo].['+@objectname+'] REORGANIZE'
Else
seT @sqlcommand='ALTER INDEX ['+@indexname+'] ON [dbo].['+@objectname+'] REBUILD WITH (ONLINE='+@onlineflag +')'

insert into #work_to_do1
select  (@sqlCOMMAND)


seT @sqlcommand='UPDATE STATISTICS [dbo].['+@objectname+'] ['+@indexname+'] WITH FULLSCAN'

insert into #work_to_do1
select  (@sqlCOMMAND)

FETCH NEXT
FROM Index_cursor
INTO  @objectname,@indexname,@frag,@onlineflag,@allow_page_locks

END;

-- Close and deallocate the cursor.
CLOSE Index_cursor;
DEALLOCATE Index_cursor;


/*********************/
DECLARE cmd_cursor
CURSOR FOR select distinct sqlcommand
FROM    #work_to_do1

-- Open the cursor.
OPEN cmd_cursor;

FETCH NEXT
FROM cmd_cursor
INTO   @sqlcommand

WHILE (1 = 1)
BEGIN;

IF @@FETCH_STATUS < 0 BREAK;

print  (@sqlCOMMAND)

FETCH NEXT
FROM cmd_cursor
INTO   @sqlcommand

END;

-- Close and deallocate the cursor.
CLOSE cmd_cursor;
DEALLOCATE cmd_cursor;



DROP TABLE #work_to_do
DROP TABLE #work_to_do1


Friday, May 16, 2014

To Find Index Creation Date

-- To find Index Creation Date


SELECT schema_name(o.schema_id) AS SchemaName

      , object_name(si.object_id) AS TableName

      , si.name AS IndexName

      , STATS_DATE(i.object_id, i.index_id) AS StatDate

FROM sys.indexes si

JOIN sys.objects o ON si.object_id = o.object_id

JOIN sys.indexes i ON i.object_id = si.object_id AND i.index_id = si.index_id

WHERE o.type <> 'S' -- exclude system objects

  AND STATS_DATE(i.object_id, i.index_id) IS NOT NULL;

===============================================================
  OR



select
    i.name as IndexName,
    o.name as TableName,
    ic.key_ordinal as ColumnOrder,
    ic.is_included_column as IsIncluded,
    co.[name] as ColumnName,
    o.create_date
from sys.indexes i
join sys.objects o on i.object_id = o.object_id
join sys.index_columns ic on ic.object_id = i.object_id
    and ic.index_id = i.index_id
join sys.columns co on co.object_id = i.object_id
    and co.column_id = ic.column_id
where i.[type] = 2
--and i.is_unique = 0
--and i.is_primary_key = 0
--and o.[type] = 'U'
--and ic.is_included_column = 0
order by o.[name], i.[name], ic.is_included_column, ic.key_ordinal;

=====================================================================


OR

--sort as you wish, you have the most recently created index first

select
crdate,
i.name,
object_name(o.id)
-- , * --optionally
from
sysindexes i
join sysobjects o ON o.id = i.id
order by
crdate desc

Saturday, May 10, 2014

File space Alert for Databases


go

drop table #templist
-- =============================================
-- Declare and using a READ_ONLY cursor
-- =============================================
set nocount on
select [name] as dbname
, fileid, sf.groupid, grp=left([groupname],20), lname=left([name],20), size_mb=[size]/128 
  ,used_mb=FILEPROPERTY([name], 'SpaceUsed')/128
  ,file_growth=case when (sf.status&0x100000) > 0 then str(growth)+' %'
     else str(growth/128)+' mb' end
  ,max_mb = case when [maxsize]<0 then 'Unrestricted'
     else str([maxsize]/128) end
  ,phname=left(filename,70)  into #templist
  from 
   sysfiles sf left outer join  sysfilegroups sfg on sf.groupid=sfg.groupid
where 1 = 2

alter table  #templist add UpdateStatement varchar(512)


DECLARE Cur_SysDB CURSOR
READ_ONLY
FOR 
SELECT name FROM SYSDATABASES 

DECLARE @name varchar(40)
OPEN Cur_SysDB

FETCH NEXT FROM Cur_SysDB INTO @name
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
  exec ('insert into #templist 
  select ''' + @name + ''' as Dbnamename,  fileid, sf.groupid, grp=left([groupname],20), lname=left([name],20), size_mb=[size]/128 
  ,used_mb=FILEPROPERTY([name], ''SpaceUsed'')/128
  ,file_growth=case when (sf.status&0x100000) > 0 then str(growth) + '' %''
     else str(growth/128)+'' mb'' end
  ,max_mb = case when [maxsize]< 0 then ''Unrestricted''
     else str([maxsize]/128) end
  ,phname=left(filename,70),
    ''use [' + @name + '] ; update #templist set used_mb = FILEPROPERTY([name], ''''SpaceUsed'''')/128
from [' + @name + '].dbo.sysfiles sf left outer join  [' + @name + '].dbo.sysfilegroups sfg on sf.groupid=sfg.groupid 
  where  phname collate database_default = filename '' as updatestatement
  from ' + @name 
   + '.dbo.sysfiles sf left outer join  ' + @name + '.dbo.sysfilegroups sfg on sf.groupid=sfg.groupid   order by 1')
END
FETCH NEXT FROM Cur_SysDB INTO @name
END

CLOSE Cur_SysDB
DEALLOCATE Cur_SysDB


go

-- drop table #templist
DECLARE Cur_SysDBUpdate CURSOR
READ_ONLY
FOR 
SELECT distinct UpdateStatement  FROM #templist

DECLARE @updatestatement varchar(512)
OPEN Cur_SysDBUpdate

FETCH NEXT FROM Cur_SysDBUpdate INTO @updatestatement
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
      Exec (@updatestatement)
END
FETCH NEXT FROM Cur_SysDBUpdate INTO @updatestatement
END

CLOSE Cur_SysDBUpdate
DEALLOCATE Cur_SysDBUpdate

go
-- select dbname , case when used_mb > 0 then cast(used_mb as decimal(5,2)) / cast(size_mb as decimal(5,2) * 100 else 0.00 end from #templist
set nocount off
go
select dbname, grp, lname, size_mb, used_mb,cast( case when used_mb > 0 then 
convert(dec(29,2), used_mb) / cast(size_mb as decimal(29,2)) * 100 
else '0' end as decimal(5,2)) USagepercent , phname,file_growth, max_mb
  from #templist where dbname like 'tempd' and grp is not null
order by 4 desc